背景介绍
因工作需求,目前需要采用UDP协议来存储用户日志信息,目前采用了JAVA 和 Golang 两种途径。
Linux内核优化(非常重要)
可以使用netstat -su 查看UDP是否有错包,如果查看到有UDP receive errors,可以调整UDP缓冲区的大小以应对大规模请求,主要参数如下
net.core.rmem_max=26214400
net.core.rmem_default=26214400
客户端情况介绍
客户端采用PHP语言进行编写,由于PHP底层采用C实现,所以UDP客户端的性能应该算是最佳了,相关代码如下:
<?php
$islocalUdp = true;
$server_ip = '127.0.0.1';
$server_port = 10000;
$message = 'loginfo';
if($islocalUdp){
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$ret = socket_sendto($socket, $message, strlen($message), 0, $server_ip, $server_port);
}else{
$message = "$server_ip**$server_port**$message";
$ret = sendDataUds ($message,3,'/dev/shm/unix_udp_socks.sock');
}
?>
JAVA服务端介绍
JAVA使用名声很大的Netty 网络包。
Golang 服务端介绍
Golang服务端采用Net包中的ListenUDP进行程序编写,由于目前没有对大日志进行测试,所以不进行缓冲区中转编程,相关代码如下:
package main
import (
"fmt"
"log"
"net"
)
const (
BUF_SIZE = 1024
)
func main() {
udp_addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:10000")
if err != nil {
log.Fatal(err)
}
pc, err := net.ListenUDP("udp", udp_addr)
if err != nil {
log.Fatal(err)
}
totalCount := -1
defer pc.Close()
for {
totalCount++
data := make([]byte, BUF_SIZE)
n, remoteAddr, err := pc.ReadFromUDP(data)
if err != nil {
fmt.Printf("error during read: %s", err)
}
_, err = pc.WriteToUDP([]byte("udp recv"), remoteAddr)
if err != nil {
fmt.Printf(err.Error())
}
}
}
测试报告
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:
评论已关闭