网卡丢包怎么办?或者再具体点,使用ifconfig查看网卡,发现有dropped统计时可以从哪些方面进行调查?要想知道为什么丢包,首先要弄清楚接收数据包的流程。
Linux系统从网卡收到数据包到最终上层应用处理之间涉及到多个模块,包括物理硬件、驱动、缓存队列、内核、再到应用程序。如下图,其中任一模块出问题都有可能导致网卡丢包。
如上图,接收数据包会遵循硬件(device)->内核(kernel)->用户态应用(user)这一处理流程。
1. 数据包到达网卡(物理硬件)时,对数据包进行CRC校验,如果校验无误,就把帧头去掉,把数据包拷贝(DMA)到内存的ringbuffer中,然后网卡会向cpu发送一个irq硬中断,cpu在收到硬中断后会通知驱动处理数据。
2. 驱动收到cpu的通知,会开启NAPI(一种轮询机制,能够避免频繁触发中断),然后发出软中断。软中断会触发ksoftirqd内核线程进行数据处理,ksoftirqd会将数据包封装为skb结构,然后上送到内核协议栈。
3. 协议栈分层对数据进行解析,如解析以太头、IP头、TCP/UDP头等,随后将数据拷贝到socket buffer中。
4. 用户态应⽤程序从socket buffer 中读取数据,进行业务处理。
可以了解到接收数据包主要会涉及⽹卡设备、⽹卡驱动、内核协议栈三⼤类。排查丢包原因也要从这三类入手。
1. Ring Buffer溢出
1) 数据帧由物理介质到达网卡(NIC)后,首先会写入设备内部缓冲区Ring Buffer中,再向cpu发送硬中断。
2) cpu收到硬中断后通知网卡驱动,驱动程序触发Softirq,由ksoftirqd内核线程从Ring Buffer中消费数据。
Ring Buffer的大小因网卡设备而异。当网络数据包到达(生产)的速率快于内核处理(消费)的速率时,Ring Buffer很快会被填满,新来的数据包将被丢弃。
查看方式
通过ethtool或/proc/net/dev可以查看因Ring Buffer满而丢弃的包统计,在统计项中以fifo标识:
ethtool -S ens5f0 | grep rx_fifo
cat /proc/net/dev
查看网卡Ring Buffer最大值和当前设置
ethtool -g ens5f0
解决方案
修改网卡接收与发送硬件缓存区大小
ethtool -G ens5f0 rx 4096 tx 4096
2. 网卡端口协商丢包
接收设备的网卡会和与之相连的另一块网卡协商传输速率,正常情况下,两端的传输速率硬相同,但仍有可能出现两端速率不一致的情况。
查看方式
使用ethtool查看网卡配置状态:
ethtool ens5f0
黄色框中为传输速率,红色框为是否开启自动协商。
解决方案
ethtool -r ens5f0;
ethtool -s ens5f0 speed 1000 duplex full autoneg off
3. 网卡流控丢包
查看方式
1) 查看流控统计:
ethtool -S ens5f0 | grep control
rx_flow_control_xon是在网卡的RX Buffer满或其他网卡内部的资源受限时,给交换机端口发送的开启流控的pause帧计数。对应的,tx_flow_control_xoff是在资源可用之后发送的关闭流控的pause帧计数。
2) 查看网络流控配置:
ethtool -a ens5f0
解决方案
关闭网卡流控
- ethtool -A ethx autoneg off //自协商关闭
- ethtool -A ethx tx off //发送模块关闭
- ethtool -A ethx rx off //接收模块关闭
4. CRC校验错误
查看方式
查看crc校验统计:
ethtool -S ens5f0 | grep crc_errors
解决方案
一般试着重新插拔一下网线,或者换一根网线,排查插口是否符合端口规格等。
5. 报文长度丢包
网卡有接收正确报文长度范围,一般正常以太网报文长度范围:64-1518,发送端正常情况会填充或者分片来适配,偶尔会发生一些异常情况导致发送报文不正常丢包。
查看方式
ethtool -S ens5f0|grep length_errors
解决方案
1 调整接口MTU配置,是否开启支持以太网巨帧;
2 发送端开启PATH MTU进行合理分片;