本期分享专家:枫凡,曾就职于安恒信息。目前在阿里云从事ECS产品的技术支持,专注于云计算相关的安全问题以及网络问题。坚信:“不忘初心,方得始终

4955cb39938c2b9196b95cf08d1a3ffb63d9a495


在你发现网站访问慢、业务不稳定的时候,你是不是也发现了服务器的ping值很高,还经常会有丢包的情况,这些病症技术专家经常见到,也经常帮客户分析治疗此类病症,总结起来可能的原因有这几点:运营商的网络影响、带宽跑满啦、本地网络问题、系统层面的问题等。 不过专家还说了 ,丢包只是问题的现象,要解决丢包的病症还得找到病根。今天专家枫凡坐诊为您分析丢包问题,一个案例教你如何排查系统原因导致的丢包问题。


问题背景

问题实例
公网IP地址  xx.xx.138.206

用户业务说明
用户业务基于UDP 协议,ECS 安装 CentOS 6.5,作为中转服务器,收到客户端发送的UDP报文请求后,根据配置将客户端UDP报文请求转发到其它业务服务器。出入流量大致持平,即流入多少流量,流出多少流量。
客户业务正常服务时, ECS 服务器整体的公网出入 PPS(Packets Per Second) 均在7W 左右。
 
问题现象:
客户发现业务异常,有如下表现:
1、整体的流量情况不符合预期,流入流量明显大于流出流量。
2、外部IP地址ping xx.xx.138.206 该IP地址都存在丢包的情况。从本机ping 外部IP地址不存在丢包情况。
3、查看用户历史数据,在业务高峰期流量高于60M左右时,会出现不稳定的情况。
如下图:
714be1d3faf2f6121498d7531aa08604ba36b292

排查思路


根据用户的反馈,核心问题是UDP流量转发异常,同时发现Ping丢包的症状。如下是问题定位过程的步骤摘要:
1、通过双向MTR命令测试,发现ECS对外访问客户端的MTR报文第1跳就丢包。通过ECS内部Tcpdump抓取网络包也发现内部收到ICMP Request后并不响应。我们认为该问题与OS内部相关,与中间网络无关。
2、通过TOP命令查看OS内部的负载情况,发现CPU 0 跑满,通过调整CentOS启动参数保证软中断在多个CPU核之间均匀处理。
3、通过检查dmesg命令输出以及/var/log/messages等日志,发现有”Bad Checksum”错误和” _ratelimit: 25 callbacks suppressed”信息,通过临时关闭Checksum以排除是否是因为Checksum处理错误造成影响。
4、在进行上述分析时,用户已经将转发业务关闭,但仍然发现出现Ping丢包的情况。
5、通过Sar命令排查系统内部连接数情况,Netstat命令查看网络统计信息发现大量ICMP Type 3报文,通过抓包也确实发现因为业务关闭,造成ECS 返回大量ICMP Type 3(Port Unreachable)消息。我们怀疑内核在大量ICMP Type 3报文的处理下,可能对ICMP Request报文处理存在问题。通过IPTables关闭发送ICMP Port Unreachable消息测试。
6、关闭响应ICMP Type 3后,发现外部Ping该ECS恢复正常。同时将转发业务开启,发现可以正常处理业务。

详情请参考如下逐项的定位测试。

1、网络测试分析

通过MTR定位丢包点,如下图双向MTR结果:
  • 从ECS到客户端第一跳就开始丢包;
  • 从客户端到ECS,最后一跳才丢包。
结论:结合抓包也发现系统收到ICMP Request后不响应,判断异常是系统内部的原因导致。
  027a01b6227a28d5ac228518b3d50512242a8f79
  f6d083582617fed8a125933e23c7b06189cd5af3

2、CPU负载情况分析

通过Top命令,发现ECS CPU 0跑满,该情况会导致网卡软中断的处理存在问题,可能出现丢包情况。
  fccac31f7e0ac81a7c17431cc5ce2bf0ac3ff902
为了解决该问题,修改Linux内核参数调优中断的使用。
具体见:附3。
处理完成后效果如下:
c173b54bd719b7981329ebcb2be51ed4ed212335
 
可以看到来自网卡的网络包处理的软中断在多个CPU核上均匀处理。

3、系统日志层面分析

dmesg命令查看日志发现异常
如下内容的报文:

UDP: bad checksum. From xx.xx.86.85:54455 to xx.xx.138.206:10315 ulen 16


  784bdd6f6fb0d18266189dd142d9a38e12da5a1f
怀疑是否是由于checksum校验问题导致的,于是为了排除干扰,先关闭Checksum Offload功能。
通过如下命令关闭网卡checksum offload:

ethtool -K eth1 tx off


关闭后结果如下图:
bd0dc28e9c027e768359ea3417175c437cefde50
 
messages以及dmesg中都出现了如下的信息说明

_ratelimit: 25 callbacks suppressed


怀疑该提示为日志限速,是由大量的类似如下的报文在打印到日志中,不影响业务。

UDP: bad checksum. From xxx.xx.86.85:54455 to xx.xx.138.206:10315 ulen 16


4、网络层面分析
用户临时将转发业务关闭,但是客户端的流量仍然发送到该ECS。从原理上来说,转发关闭后,该ECS的出流量应该降低很多,但是通过监控查看发现流量,特别是PPS没有太大的变化。
如下通过Sar和Netstat命令在系统内部进行分析:

步骤1:通过Sar查看连接数信息

使用命令

sar -n DEV 1


查看关闭业务后还是有大量的连接数,
54fc364160b45bbf0c47896f5ad72f97173adbd3
  
步骤2:通过Netstat检查各网络协议处理情况

使用命令netstat -ts进行连接数的统计查看。如下图:IcmpMsg:中的OutType3类型有非常大的计数。
52a24aeb12ca385c4253e88f4b1fc2598d4dce4c 

注:关于netstat –ts的详细介绍见:附1
我们判断大量ICMP Out Type 3报文与用户业务场景有关,由于用户的业务类型为转发类型的,即使关闭了业务,但是还是有流量流入的。UDP端口关闭监听,在收到报文的情况下,系统会响应ICMP Port Unreachable报文。

步骤3:抓包核实

通过抓包确实发现了系统有Type 3的回包ICMP destination-unreachable
由于端口不通,主机向客户端返回端口不可达的报文。
注:详细的介绍见”附2”
问题定位以及解决


怀疑点:

由于ICMP报文的原因,导致PPS无法有效的下降,占用CPU资源;同时考虑大量ICMP报文的发送,导致内核在处理ICMP协议时出现问题。

跟进方案:

使用系统防火墙IPTables禁止destination-unreachable类型的报文,命令如下:
iptables -I OUTPUT -p icmp --icmp-type destination-unreachable -j DROP
注:该配置会影响到ICMP Destination Unreachable的响应,目前仅作为临时方案。
7f115cc8de603fb9bdd7418af8cfbb62a0484c8c 
关闭后查看iptables结果如附件,拦截了大量的请求,有效的降低CPU资源消耗。
  1c77426a670394851ee7d998c495abf1d94dbc88

在系统内部使用命令查看

sar -n DEV 1 10000


发送的报文明显减少,如下图
81dbdfc06ac1e72ac108b9ad23f9828100ee477c
添加后测试用户反馈测试正常。
  7976cfccfd53d801b5269da092385ce475e66024

原因分析:

业务停止后,依然有流量进入服务器,此类情况OS都会回复ICMP destination unreachable消息,海量的ICMP处理可能导致内核处理真正的ICMP Request消息存在问题。目前禁用ICMP Destination Unreachable消息后ECS Ping正常。
用户后续恢复业务使用,反馈业务正常。

关于该问题的本质应该还是在于之前的CPU 0跑满的问题。但在排查的过程中,由于用户停止了应用程序,导致ICMP destination Unreachable 消息影响了系统对网络ICMP Request的处理,误导了排查问题的方向。

通过使用netstat命令、抓包等手段,合理的定位到问题点,先解决了ICMP destination Unreachable的影响,同时通过增加多个CPU处理网卡中断,有效提升了网络流量的处理效率,解决了问题。

附1:关于netstat -ts的介绍

netstat命令大家非常熟悉,一般用户查看系统开放的端口信息和连接建立情况。在排查问题的时,经常使用netstat –antp.
这里介绍下关于netstat 中的参数s
-s或--statistice   显示网络工作信息统计表。
-t (tcp)仅显示tcp相关选项
-u (udp)仅显示udp相关选项
netstat -st输出的两个重要信息来源分别是/proc/net/snmp和/proc/net/netstat
如果希望更多了解参数,建议通过“TCP SNMP counters”搜索了解详情。 
本例中主要关注ICMP,ICMP协议的统计时在TCP以及UDP下的统计结果类似,类似如下(截图命令执行部分结果):

[root@xxxxx ~]# netstat –ts

IcmpMsg:

    InType0: 133

    InType3: 3934246

    InType8: 2211

    InType11: 236

    OutType0: 2211

    OutType3: 752659455      #OUTType的计数有752659455该值判断异常。

    OutType8: 147

   

   
附2:关于ICMP协议Type 3的介绍

ICMP经常被认为是IP层的一个组成部分。它传递差错以及其他需要注意的信息。ICMP报文通常被IP层或四层协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。
ICMP报文是在IP数据报内部被传输的,它封装在IP数据报内。关于ICMP的正式规范参见RFC792.
端口不可达报文,它是ICMP目的不可到达报文中的一种, 以此来看看ICMP差错报文中所附加的信息。举例UDP的ICMP端口不可达;UDP的规则之一是,如果收到一份UDP数据报而目的端口与某个正在使用的进程不相符,那么UDP返回一个不可达报文。
Type:3 Code:3为 端口不可达
报文样例:
  399163a8683527db812ad95736f3a8823ca61a62


附3:CPU 0跑满导致网络丢包的处理方法

问题原因:
 OS 默认所有的网络中断都是集中在 CPU 0 上的,所以 CPU 0 一跑满就出现丢包。
问题处理:

注:
1、重启生效
2、适用于内核2.6.32版本(CentOS 6系列),其他内核不适用。

/boot/grub/menu.lst中加入nox2apic参数

如: kernel /boot/vmlinuz-2.6.32-431.23.3.el6.x86_64 ro root=UUID=94e4e384-0ace-437f-bc96-057dd64f42ee rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet nox2apic


系统层面的丢包问题你知道怎么解了吗?欢迎大家留言讨论,如果有想了解的技术也可以随时留言,我们下期再见。




Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐