程序背景

程序是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_queuerx_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 ErrorsUdp 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 LimitsUDP Drops on Linux

Netty_UDP丢包解决的更多相关文章

  1. winxp系统连接服务器丢包解决方法

    winxp系统连接服务器丢包解决方法 MFC编写一个打开网页的程序,发生异常没有获取到数据. 分析步骤: 1. 用getLastError()获取到的信息,(2)- 系统找不到指定的文件. 2. 用浏 ...

  2. Android Studio多Module使用 aar 依赖包 丢包解决

    FAQ: AAR打包引用丢包问题, jar, aar, dependency 嵌套层级依赖的丢失 问: aar包中,如何包含第三方依赖库? 如果直接作为module 依赖是没有问题的,但是如果打包成a ...

  3. 出现丢包解决方法(ping: sendmsg: Operation not permitted)

    故障排查: 早上突然收到nagios服务器check_icmp的报警,报警显示一台网站服务器的内网网络有问题.因为那台服务器挂载了内网的NFS,因此内网的网络就采用nagios的check_icmp来 ...

  4. UDP丢包和无序 问题的解决方法

    最近在做一个项目,在这之前,做了个验证程序. 发现客户端连续发来1000个1024字节的包,服务器端出现了丢包现象. 纠其原因,是服务端在还未完全处理掉数据,客户端已经数据发送完毕且关闭了. 我用过s ...

  5. Linux UDP严重丢包问题的解决

    测试系统在Linux上的性能发现丢包率极为严重,发210000条数据,丢包达110000之巨,丢包率超过50%.同等情形下Windows上测试,仅丢几条数据.形势严峻,必须解决.考虑可能是因为协议栈B ...

  6. AR8033 1000M模式下ping包丢包率过大分析与解决

    1 现象 近期对一款基于QCA方案.有线Phy为AR8033.WiFi双频且支持iEEE802.11AC的WLAN产品进行了深度验证,发现有线口同部分PC机直连时,WiFi终端ping 该PC机时总是 ...

  7. VS2015编译FFMPEG,修改FFmpeg缓冲区大小解决实时流解码丢包问题,FFmpeg错误rtsp流地址卡死的问题,设置超时

    之前尝试过很多网上利用Windows编译FFmpeg的文章,都没有办法编译X64位的FFmpeg,有些教程中有专门提到编译64位的FFmpeg需要下载mingw-w64-install,但是编译的过程 ...

  8. socket编程解决粘包和丢包问题

    ##socket 丢包粘包解决方式 采用固定头部长度(一般为4个字节),包头保存的是包体的长度 header+body 包头+包体 下面的例子不是按照上图中规定的格式编写的,但是思路都是一样的,先读出 ...

  9. 用ethtool 命令解决Linux 网卡丢包【转】

    转自:https://blog.csdn.net/chengxuyuanyonghu/article/details/73739516 生产中有一台Linux设备并发比较大,droped包比较多,尤其 ...

随机推荐

  1. RadioButton与CheckBox

    笔者长期从事于数据库的开发,算了,不提当年了,因为一直用的是小语种(PowerBuilder),还是来说说这两个最常见的控件吧! RadioButton(单选)和CheckBox(多选) 先来看看继承 ...

  2. android 自定义通知栏

    package com.example.mvp; import cn.ljuns.temperature.view.TemperatureView;import presenter.ILoginPre ...

  3. ASP.NET MVC 3 网站优化总结(一) 使用 Gzip 压缩

    网站开启 Gzip 压缩的好处相信很多人都已经清楚,这样做可以提高网站的性能.那么为什么很多网站没有开启 Gzip 压缩功能呢?原因有4点:防病毒软件.浏览器 bug.网站代理和服务器未配置. 使用 ...

  4. 基于InstallShield2013LimitedEdition的安装包制作

    在VS2012之前,我们做安装包一般都是使用VS自带的安装包制作工具来创建安装包的,VS2012.VS2013以后,微软把这个去掉,集成使用了InstallShield进行安装包的制作了,虽然思路差不 ...

  5. freeswitch注册过程分析

    操作系统:debian8.5_x64freeswitch 版本 : 1.6.8 本文仅描述sip注册的简单场景,即话机直接向处于同一个局域网的fs进行注册. SIP协议的消息结构 消息框架 SIP协议 ...

  6. Javascript——arguments的shift问题谈方法“借用”

    今天本来运行了打算这样的方法 arguments.shift() (shift方法是删除数组的第一个元素,例如var arr=[1,2,3,4,5]执行var a=arr.shift();之后,a的值 ...

  7. RSA算法原理

    一直以来对linux中的ssh认证.SSL.TLS这些安全认证似懂非懂的.看到阮一峰博客中对RSA算法的原理做了非常详细的解释,看完之后茅塞顿开,关于RSA的相关文章如下 RSA算法原理(一) RSA ...

  8. AD域撤销域用户管理员权限方案

    一.简介 公司大部分主机加入域已有一段时间了,由于某软件没管理员权限不能执行,所以管理员权限一直没撤销,不能完全实现域的管理效果.但起码实现了域用户脱离不了域的控制:http://www.cnblog ...

  9. 安装centos后无法引导启动windows7的解决方法

    在电脑Windows7系统上安装Centos7,安装后找不到Windows7引导菜单. 原因:因为CentOS 7已采用新式的grub2系统,所以需要进入/boot/grub2目录后使用vi编辑gru ...

  10. appscan 对api的手工检测

    AppScan 在 API 安全测试中的实例介绍 在本项目中,API 遵循标准的的 REST 架构和背端服务器进行通信.针对 API 的功能测试由两部分组成:一部分是用一个 Web 的测试页面直接实现 ...