Bal*_*ala 20 linux udp epoll linux-kernel
我写了一个简单的UDP服务器程序,以了解更多可能的网络瓶颈.
UDP服务器:创建UDP套接字,将其绑定到指定的端口和地址,并将套接字文件描述符添加到epoll兴趣列表.然后它的epoll等待传入的数据包.收到传入数据包(EPOLLIN)后,它会读取数据包并只打印接收到的数据包长度.很简单,对:)
UDP客户端:我使用了hping,如下所示:
hping3 192.168.1.2 --udp -p 9996 --flood -d 100
当我以每秒100个数据包发送udp数据包时,我没有发现任何UDP数据包丢失.但是当我泛洪udp数据包时(如上面的命令所示),我看到了重要的数据包丢失.
测试1: 当从UDP客户端泛洪26356个数据包时,我的示例程序仅接收12127个数据包,剩余的14230个数据包被内核丢弃,如/ proc/net/snmp输出所示.
cat/proc/net/snmp | grep Udp:
Udp:InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
Udp:12372 0 14230 218 14230 0
对于Test1,丢包率为~53%.
我确认在客户端和服务器端使用"ethtool -S ethX"命令在硬件级别上没有太多损失,而在应用程序级别,我看到如上所述损失53%.
因此,为了减少数据包丢失,我尝试了以下方法:
- 使用renice命令提高了示例程序的优先级.
- 增加接收缓冲区大小(在系统级和进程级)
将优先级提高到-20:
renice -20 2022
2022(进程ID)旧优先级0,新优先级-20
将接收缓冲区大小增加到16MB:
在Process Level:
int sockbufsize = 16777216;
setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,(char*)&sockbufsize,(int)sizeof(sockbufsize))
在内核级别:
cat/proc/sys/net/core/rmem_default
16777216
cat/proc/sys/net/core/rmem_max
16777216
完成这些更改后,执行Test2.
测试2: 当1985076数据包从UDP客户端泛洪时,我的示例程序接收到1848791个数据包,剩余的136286数据包被内核丢弃,如/ proc/net/snmp输出所示.
cat/proc/net/snmp | grep Udp:
Udp:InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
Udp:1849064 0 136286 236 0 0
对于Test2,丢包率为6%.
数据包丢失显着减少.但我有以下问题:
谢谢你的帮助和时间!
如果硬件级别没有丢包,那么应该主要是内存问题,您应该能够调整内核配置参数以达到 0 丢包(显然,您需要一个合理的平衡硬件来处理您正在接收的网络流量)。
我认为您缺少netdev_max_backlog这对于传入数据包很重要:
当接口接收数据包的速度快于内核处理数据包的速度时,在 INPUT 端排队的最大数据包数。