【Linux中UDP服务丢包率过高排查思路】

一、概述

在Centos7服务器中部署了基于Netty实现的UDP服务,用来采集日志。将数据发送到UDP服务端之后,没有复杂业务处理,直接写入本地的log文件中。经过监控分析,成功找出优化方案,将目标3000QPS每秒丢包率3%降至0.00002%,5000QPS也比较良好。

二、监控UDP消息每秒收发数据

1、使用 netstat -s -u 命令可以监控UDP服务统计信息

在这里插入图片描述
netstat -s -u命令,统计指标主要数据说明

  • packets received:接收到的UDP数据包数量。
  • packets to unknown port received:接收到未知端口的UDP数据包数量。
  • packet receive errors:接收UDP数据包时发生的错误数量。
  • packets sent:发送的UDP数据包数量。
  • receive buffer errors:接收缓冲区错误的数量。
  • send buffer errors:发送缓冲区错误的数量。
  • InNoRoutes:无法路由的数据包数量。
  • InMcastPkts:接收到的多播数据包数量。
  • OutMcastPkts:发送的多播数据包数量。
  • InBcastPkts:接收到的广播数据包数量。
  • InOctets:接收到的总字节数。
  • OutOctets:发送的总字节数。
  • InBcastPkts:接收到的广播数据包数量。

主要关注packets received、acket receive errors、receive buffer errors三个指标

2、使用 netstat -uap 命令可以监控UDP服务统计信息

在这里插入图片描述
netstat -uap命令下的一些常见指标的含义:

  • Proto: 表示网络协议类型,通常为UDP。
  • Recv-Q: 表示接收队列的大小,即等待被应用程序读取的数据包数量。
  • Send-Q: 表示发送队列的大小,即等待被网络发送的数据包数量
  • Local Address: 表示本地地址和监听端口。
  • Foreign Address: 表示远程地址和端口,如果有的话。
  • State: 表示连接状态,对于UDP协议通常为"-".
  • PID/Program name: 表示与该连接或监听端口相关联的进程ID和程序名称

基于业务,主要关注Recv-Q指标值来做分析

3、编写脚本记录每秒以上两种信息的变化

将netstat -s -u、netstat -uap命令返回监控信息保存到文本中,每秒保存一次

  1. 使用vi xx.sh命令创建脚本
#!/bin/bash
step=1
for (( i = 0; i < 60; i = (i+step) )); do
    echo "$(date) $(netstat -uap)" >> /opt/udpSocket.txt
    sleep $step
done
exit 0
#!/bin/bash
step=1
for (( i = 0; i < 60; i = (i+step) )); do
    echo "$(date) $(netstat -s -u)" >> /opt/1.output.txt
    sleep $step
done
exit 0

  1. 使用crontab -e 创建定时任务
* * * * * sh /opt/test.sh
* * * * * sh /opt/test1.sh

4、使用Jmeter进行UDP端口压测

三、分析保存的监控指标数据

  1. 将两个监控数据文件中,时间和packet receive errors、时间和Recv-Q进行分析,计算丢包数在发送样本的占比

  2. 使用Excel对两份数据建立数据透视图
    Alt
    在这里插入图片描述

  3. packet receive errors指标错误数和receive buffer errors错误数一致,且发送条数减去日志文件写入条数等于packet receive errors错误数,初步得出结论缓冲区错误是丢包率过高的主要原因。

  4. 分析Recv-Q指标,数值持续保持峰值,很少有为0的时候,说明应用来不及读取接收缓冲区中的数据,接收缓冲区一直是满着的状态,更加证明Linux内核中默认socket接收缓冲区最大值满足不了当前的并发情况,需要增加缓冲区大小。

四、解决方案

  1. 增加用户态应用程序处理能力,使用零拷贝、IO多路复用、多线程绑定一个端口、增加应用程序UDP服务端中接收缓冲区的大小等措施。(例:【基于Netty实现Epoll机制的UDP接收服务】)
  2. 修改内核参数,增加内核层面接收缓冲区的大小。
    (1). 使用sysctl net.core.rmem_default、sysctl net.core.rmem_max命令查看系统内核中套接字接收缓冲区默认大小在这里插入图片描述
    (2).临时有效方式:使用sysctl -w net.core.rmem_default=1048576、sysctl -w net.core.rmem_max=1048576命令修改接收缓冲区大小改为1MB
    (3).永久有效方式:
打开终端,并使用 root 或具有管理员权限的用户登录。
编辑 /etc/sysctl.conf 文件,可以使用任何文本编辑器打开该文件。
在文件的末尾添加以下行来设置接收缓冲区大小:
net.core.rmem_default = <new_size>
net.core.rmem_max = <new_size>
其中,<new_size> 是你想要设置的新的接收缓冲区大小。
保存并关闭文件。
运行以下命令以使更改生效:
sudo sysctl -p
这将重新加载 /etc/sysctl.conf 文件中的配置,并使更改生效。
  1. 重新压测,计算丢包率。如果数据不理想,重复分析packet receive errors、和Recv-Q指标,分析Recv-Q指标每秒分布情况,看接收缓冲区是否够用。

五、内核中接收缓冲区大小的影响范围分析

使用netstat -anp 命令查看内核中接收缓冲区的个数,每个TCP、UDP都会有对应的一个接收缓冲区,假如应用程序中有使用tomcat,则内存使用范围在tomcat200最大线程 * 1MB+其他运行线程 *1MB,以本地虚拟机为例,默认有21个接收缓冲区,再加上tomcat的默认最大200线程,内核中接收缓冲区内存占用在200多MB。对其他业务影响不大。
在这里插入图片描述

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值