背景介绍
因工作需求,目前需要采用UDP协议来存储用户日志信息,目前采用了JAVA 和 Golang 两种途径。
#Linux内核优化(非常重要) 可以使用netstat -su 查看UDP是否有错包,如果查看到有UDP receive errors,可以调整UDP缓冲区的大小以应对大规模请求,主要参数如下
1net.core.rmem_max=26214400
2net.core.rmem_default=26214400
#客户端情况介绍 客户端采用PHP语言进行编写,由于PHP底层采用C实现,所以UDP客户端的性能应该算是最佳了,相关代码如下:
1<?php
2$islocalUdp = true;
3$server_ip = '127.0.0.1';
4$server_port = 10000;
5$message = 'loginfo';
6
7if($islocalUdp){
8 $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
9 $ret = socket_sendto($socket, $message, strlen($message), 0, $server_ip, $server_port);
10}else{
11 $message = "$server_ip**$server_port**$message";
12
13 $ret = sendDataUds ($message,3,'/dev/shm/unix_udp_socks.sock');
14}
15?>
#JAVA服务端介绍 JAVA使用名声很大的Netty 网络包。
#Golang 服务端介绍 Golang服务端采用Net包中的ListenUDP进行程序编写,由于目前没有对大日志进行测试,所以不进行缓冲区中转编程,相关代码如下:
1package main
2
3import (
4 "fmt"
5 "log"
6 "net"
7)
8
9const (
10 BUF_SIZE = 1024
11)
12
13func main() {
14 udp_addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:10000")
15 if err != nil {
16 log.Fatal(err)
17 }
18 pc, err := net.ListenUDP("udp", udp_addr)
19 if err != nil {
20 log.Fatal(err)
21 }
22 totalCount := -1
23 defer pc.Close()
24
25 for {
26 totalCount++
27 data := make([]byte, BUF_SIZE)
28 n, remoteAddr, err := pc.ReadFromUDP(data)
29 if err != nil {
30 fmt.Printf("error during read: %s", err)
31 }
32 _, err = pc.WriteToUDP([]byte("udp recv"), remoteAddr)
33 if err != nil {
34 fmt.Printf(err.Error())
35 }
36 }
37}
#测试报告
1. 100线程、100*100请求
JAVA:
丢包率:0
聚合报告:
图形报告
Golang:
丢包率:0
聚合报告:
图形报告
2. 500线程、500*100请求
JAVA:
丢包率:0
聚合报告:
图形报告
Golang:
丢包率:0
聚合报告:
图形报告
2. 5000线程、5000*100请求 第一轮
JAVA:
丢包率:0
聚合报告:
图形报告
响应时间图形
Golang:
丢包率:0
聚合报告:
图形报告
响应时间图形
2. 5000线程、5000*100请求 第二轮
JAVA:
丢包率:0
聚合报告:
图形报告
响应时间图形
Golang:
丢包率:0
聚合报告:
图形报告
响应时间图形
内存消耗
JAVA :
Golang: