在linux下运行一程序,需要外部发送Udp数据包作为数据来源,发送数据包约为3000/s时,发现丢包比较严重,约为25%(通过对数据包分析可知).
1. 检查设备,使用sysctl -a查看系统内核参数:
net.core.rmem_default = 20000000 (默认读缓冲大小,接收数据包,数据正常)
net.core.wmem_default = 129024 (默认写缓冲大小)
net.core.rmem_max = 20000000 (最大读缓冲大小,接收数据包,数据正常)
net.core.wmem_max = 131071
(修改系统的默认参数可以在/etc/sysctl.conf文件中修改,更常用的是在/etc/rc.local中输入编辑的命令行,系统启动时会自动执行)
#!/bin/sh
#
# This script will be executed *after* all the other init
scripts.
# You can put your own initialization stuff in here if you
don't
# want to do the full Sys V style init
stuff.
echo 256000 >
/proc/sys/vm/min_free_kbytes
sysctl -w net.core.rmem_max=20000000
net.core.rmem_default=20000000
sysctl -p
sysctl -w net.ipv4.route.flush=1
/root/ConfigScript/cupid_sys_ini
touch /var/lock/subsys/local
2. 使用netstat -su查看udp丢包(netstat -st查看tcp丢包)
[root@Wing ~]$ netstat -su
IcmpMsg: InType5: 101
InType8: 75
OutType0: 75
OutType3: 47
Udp: 38846211 packets received
16904 packets to unknown port
received.
606514 packet receive
errors
2415 packets sent IpExt: InBcastPkts: 6141
packet receive errors不断增大,根据查到的资料,原因可能有以下几种:
"packet
receive errors" usually means:
1)
data is truncated, error in checksum while copying
2)
udp queue is full, so it needs to be dropped
3)
unable to receive udp package from encapsulated socket
4)
sock_queue_rcv_skb() failed with -ENOMEM
5)
it is a short packet
6)
no space for header in udp packet when validating packet
7)
xfrm6_policy_check() fails
many
times it means the checksum is not right.
3. 尝试减少发送数据包的量,到一定程度之后,receive
errors数字渐渐不再变化.怀疑是第二条原因造成的,由于程序处理性能有限,导致无法及时从缓存中处理数据包,所以优化程序的数据包处理,发现系统容忍的接收数据包速率明显上升,但还是没有到理想的程度.
4.
正在想继续优化程序时,突然发现,由于模拟发送数据包的一个参数配置问题,导致每个数据包中包含的信息量只有标准的1/9,所以系统能处理的数据量相当于标准的1/9,调整该参数之后,系统性能明显上升,从之前稳定处理4300条/s到1w条/s.
5.
总结:主要是因为配置原因,导致模拟发送的udp数据包信息量较少,误认为系统性能低下.看来编程是个苦力活啊,细节是魔鬼.