一、消息收发流程图及丢包可能原因

centos 内核drop 丢包查看日志 linux丢包测试_客户端

1. 在网卡收包后,环形缓冲区可能会因为溢出而丢包;

2. 在链路层,可能会因为网络帧校验失败、QoS 等而丢包;

3. 在 IP 层,可能会因为路由失败、组包大小超过 MTU 等而丢包;

4. 在传输层,可能会因为端口未监听、资源占用超过内核限制等而丢包;

5. 在套接字层,可能会因为套接字缓冲区溢出而丢包;

6. 在应用层,可能会因为应用程序异常而丢包;

7. 如果配置了 iptables 规则,这些网络包也可能因为 iptables 过滤规则而丢包。

 

二、逐层排查丢包问题

 

使用hping3检查丢包情况:

centos 内核drop 丢包查看日志 linux丢包测试_客户端_02

发现问题:  50% 的丢包;RTT 的波动也仍旧很大,从 3ms 到 1s。

1. 链路层

1.1 检查虚拟网卡

执行netstat -i

centos 内核drop 丢包查看日志 linux丢包测试_客户端_03

RX-OK:接收时总包数

RX-ERR:总错误数

RX-DRP:进入 Ring Buffer 后因其他原因(如内存不足)导致的丢包数

RX-OVR:Ring Buffer 溢出导致的丢包数

从这个输出中,没发现任何错误,说明虚拟网卡没有丢包。

1.2 检查TC规则

检查 eth0 上是否配置了 tc 规则

centos 内核drop 丢包查看日志 linux丢包测试_Nginx_04

发现问题:eth0 上面配置了一个网络模拟排队规则,并且配置了丢包率为 30%

处理方法:删除 tc 中的 netem 模块

centos 内核drop 丢包查看日志 linux丢包测试_客户端_05

2. 网络层和传输层

执行 netstat -s

centos 内核drop 丢包查看日志 linux丢包测试_客户端_06

发现有5个问题,如上。

这个结果说明,TCP 协议有多次超时和失败重试,并且主要错误是半连接重置。

即:,主要的失败,是三次握手失败。

3. iptables 和内核的连接跟踪机制

3.1 内核的连接跟踪机制

centos 内核drop 丢包查看日志 linux丢包测试_客户端_07

连接跟踪数只有 182,而最大连接跟踪数则是 262144,并没有问题。

3.2 查看iptables规则

centos 内核drop 丢包查看日志 linux丢包测试_客户端_08

发现问题:两条 DROP 规则,使用 statistic 模块,进行随机 30% 的丢包

处理办法:把这两条规则直接删除

centos 内核drop 丢包查看日志 linux丢包测试_客户端_09

重新执行刚才的 hping3 命令,看看现在是否正常:

centos 内核drop 丢包查看日志 linux丢包测试_客户端_10

现在已经没有丢包了。

hping3 工具,只能验证 Nginx 的 80 端处于正常监听状态, 还没有访问 Nginx 的 HTTP 服务

执行curl 命令,检查 Nginx 对 HTTP请求的响应:

centos 内核drop 丢包查看日志 linux丢包测试_丢包_11

可以发现,这次连接超时了。

4. tcpdump

4.1  tcpdump检查丢包环节在哪里

服务端执行tcpdump 命令,抓取 80 端口的包

centos 内核drop 丢包查看日志 linux丢包测试_客户端_12

客户端执行curl命令

centos 内核drop 丢包查看日志 linux丢包测试_Nginx_13

查看 tcpdump 的输出

centos 内核drop 丢包查看日志 linux丢包测试_丢包_14

前三个包是正常的 TCP 三次握手,没问题。(SYN,SYN ACK,ACK)

四个包却是在 3 秒才收到,并且还是客户端发送过来的 FIN 包。

也就说明,客户端的连接关闭了。

4.2 重新执行 netstat -i 令,检查网卡有没有丢包

centos 内核drop 丢包查看日志 linux丢包测试_客户端_15

果然是在网卡接收时丢包了。

hping3 时不丢包,换成 GET 就收不到

4.3 检查最大传输单元MTU

centos 内核drop 丢包查看日志 linux丢包测试_丢包_16

发现问题: eth0 的 MTU 只有 100,而以太网的 MTU 默认值是 1500。

解决办法:MTU改成 1500

centos 内核drop 丢包查看日志 linux丢包测试_Nginx_17

4.4. 再次执行 curl 命令

centos 内核drop 丢包查看日志 linux丢包测试_Nginx_18

问题解决