Netty_UDP丢包解决
程序背景
程序是Java编写,基于Netty框架写的客户端及服务端。
现象
客户端大数据量持续发UDP数据,作为UDP服务器出现了部分数据频繁丢失触发程序自身重传逻辑。
通过GC日志对比发现丢包的时间点偶有处于Full GC,说明Java程序接收间歇性stop world的不是根因。
观察Udp的dump
通过watch -n 1 -d 'cat /proc/net/udp >> /usr/udpDump.txt'
在发送数据的过程中持续观察Udp缓冲区的状况
- /proc/net/udp是瞬时的Udp socket dump,另有/proc/net/udp6用于监控IPv6
- dump输出里的tx_queue是发送缓冲区,rx_queue是接收缓冲区,单位都是byte
- 如果应用层收发效率足够好,正常情况下tx_queue和rx_queue两者永远是0
- 发送数据过程中频现rx_queue>0,说明Udp缓冲区有堆积现象
- 输出解释见How to monitor Linux UDP buffer available space?、Meaning of fields in /proc/net/udp
观察Udp的stats
通过watch -n 1 -d 'netstat -su >> /usr/udpStats.txt'
持续观察Udp的stats输出
- 输出里packets received的值指应用层从读入缓冲区里取走的包
- 输出里packets to unknown port received的值指端口无应用监听而分发至该端口的包
- 输出里packet receive errors的值指Udp接收错误数,正常情况下应该是0,在观察中不停增加,证明出现Udp包溢出接收缓冲区的情况
- 发生错误的包数与接收错误数非一一对应
- 资料参见Udp Packet Receive Errors、Udp packet drops and packet receive error difference
解决问题
服务端代码优化
定论:
默认的UDP socket读缓冲区不够引发系统丢弃UDP包。
服务端代码优化设置UDP socket读缓冲区为2M,代码如下
Bootstrap selfBootStrap = new Bootstrap();
selfBootStrap.group(group);
selfBootStrap.channel(NioDatagramChannel.class);
selfBootStrap.option(ChannelOption.SO_BROADCAST, true);
// 这一行设置了UDP socket读缓冲区为2M
selfBootStrap.option(ChannelOption.SO_RCVBUF, 1024 * 2048);
selfBootStrap.handler(channelInitializer);
selfBootStrap.localAddress(selfPort);
理论上Udp socket读缓冲区设置为2M在我们的测试场景下已经足够。优化后虽有改善但仍有丢包现象。
Linux系统级调优
定论:
应用层设置了UDP socket缓冲区不一定在Linux上生效,原因在于Linux对Udp socket缓冲区存有系统级限制,超过该限制的缓冲区大小无效。
Windows对socket的缓冲区没有限制
要点分析:
Linux通过net.core.rmem_max
控制Udp的读缓冲区,通过net.core.wmem_max
控制Udp的写缓冲区。
在程序的启动sh脚本里添加如下代码修改net.core.rmem_max
# 服务器默认UDP读缓冲区最大128K。修改为2G。解决UDP丢包问题
rmemCount=`cat /etc/sysctl.conf|grep "net.core.rmem_max" | wc -l`
if [ ${rmemCount} -eq 0 ]
then
echo "net.core.rmem_max = 2147483647" >> /etc/sysctl.conf
sysctl -p
fi
脚本的作用就是修改/etc/sysctl.conf
文件,并键入sysctl -p
命令使自定义参数生效。
资料参见Improving UDP Performance by Configuring OS UDP Buffer Limits、UDP Drops on Linux
Netty_UDP丢包解决的更多相关文章
- winxp系统连接服务器丢包解决方法
winxp系统连接服务器丢包解决方法 MFC编写一个打开网页的程序,发生异常没有获取到数据. 分析步骤: 1. 用getLastError()获取到的信息,(2)- 系统找不到指定的文件. 2. 用浏 ...
- Android Studio多Module使用 aar 依赖包 丢包解决
FAQ: AAR打包引用丢包问题, jar, aar, dependency 嵌套层级依赖的丢失 问: aar包中,如何包含第三方依赖库? 如果直接作为module 依赖是没有问题的,但是如果打包成a ...
- 出现丢包解决方法(ping: sendmsg: Operation not permitted)
故障排查: 早上突然收到nagios服务器check_icmp的报警,报警显示一台网站服务器的内网网络有问题.因为那台服务器挂载了内网的NFS,因此内网的网络就采用nagios的check_icmp来 ...
- UDP丢包和无序 问题的解决方法
最近在做一个项目,在这之前,做了个验证程序. 发现客户端连续发来1000个1024字节的包,服务器端出现了丢包现象. 纠其原因,是服务端在还未完全处理掉数据,客户端已经数据发送完毕且关闭了. 我用过s ...
- Linux UDP严重丢包问题的解决
测试系统在Linux上的性能发现丢包率极为严重,发210000条数据,丢包达110000之巨,丢包率超过50%.同等情形下Windows上测试,仅丢几条数据.形势严峻,必须解决.考虑可能是因为协议栈B ...
- AR8033 1000M模式下ping包丢包率过大分析与解决
1 现象 近期对一款基于QCA方案.有线Phy为AR8033.WiFi双频且支持iEEE802.11AC的WLAN产品进行了深度验证,发现有线口同部分PC机直连时,WiFi终端ping 该PC机时总是 ...
- VS2015编译FFMPEG,修改FFmpeg缓冲区大小解决实时流解码丢包问题,FFmpeg错误rtsp流地址卡死的问题,设置超时
之前尝试过很多网上利用Windows编译FFmpeg的文章,都没有办法编译X64位的FFmpeg,有些教程中有专门提到编译64位的FFmpeg需要下载mingw-w64-install,但是编译的过程 ...
- socket编程解决粘包和丢包问题
##socket 丢包粘包解决方式 采用固定头部长度(一般为4个字节),包头保存的是包体的长度 header+body 包头+包体 下面的例子不是按照上图中规定的格式编写的,但是思路都是一样的,先读出 ...
- 用ethtool 命令解决Linux 网卡丢包【转】
转自:https://blog.csdn.net/chengxuyuanyonghu/article/details/73739516 生产中有一台Linux设备并发比较大,droped包比较多,尤其 ...
随机推荐
- ubuntu设置时区为美国中部时间西六区
查看当前ubuntu系统时区 date -R Fri, Dec :: + 显示的是东八区时间及北京时间 然后输入tzselect 按照提示修改对应时区 本例子修改为美国中部时间 西六区 ~$ tzse ...
- javaScript之BOM操作2
<!doctype html> <html lang="en"> <head> <title>Document</title& ...
- 基于SAP的中国式数据分析浅谈
大数据时代,虽然多数企业数据的应用并不能称得上是“大数据”,但也证实了数据应用的重要性和影响力.确实,数据作为企业发展的信息沉淀,已成为企业的重要资产,如何有效利用数据是每个企业必须面临的课题. 这里 ...
- 无法解决“Microsoft.SharePoint.Security, Version=15.0.0.0,”与“Microsoft.SharePoint.Security, Version=14.0.0.0”之间的冲突
VisualStudio 2013创建控制台项目,.NetFramework选为4.5.生成目标平台:x64.然后添加对Microsoft.SharePoint.dll的引用. 生成项目时," ...
- [project euler] program 4
上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...
- Eclipse中JAR System library 没有怎么添加?
1.打开 >> Eclipse 2.右击项目 >> Build path >> Configure Build path 如图1: 图1 3.进入 ...
- GridView 树形结构分组的功能
在“会飞的鱼”博客中看到GridView实现树形结构的代码,经过修改,添加了树形结构中的复选框功能,欢迎吐槽. 源地址:http://www.cnblogs.com/chhuic/archive/20 ...
- javascript函数setInterval和setTimeout的使用区别详解
setTimeout和setInterval的使用 这两个方法都可以用来实现在一个固定时间段之后去执行JavaScript.不过两者各有各的应用场景. 方 法 实际上,setTimeout和setIn ...
- archlinux 加载loop模块,且设定loop设备个数
如果loop模块没有编译进内核就要先加载loop模块 modprobe loop 然后更改/etc/modprobe.d/modprobe.conf(有些文章写是在/etc/modprobe.conf ...
- 初识WebService
一.什么是Web服务 Web服务是一种可以用来解决跨网络应用集成问题的开发模式,目的是保证不同平台的应用服务可以互操作 二.Web服务的三个核心 Soap: SOAP(Simple Object Ac ...