网络编程之网络丢包故障如何定位?如何解决?( 八 )

解决方案:

  • 关闭Nagle算法,减少小包延迟;
  • 关闭延迟ack:
sysctl -w net.ipv4.tcp_no_delay_ack=1TCP乱序丢包
此时TCP会无法判断是数据包丢失还是乱序,因为丢包和乱序都会导致接收端收到次序混乱的数据包,造成接收端的数据空洞 。TCP会将这种情况暂定为数据包的乱序,因为乱序是时间问题(可能是数据包的迟到),而丢包则意味着重传 。当TCP意识到包出现乱序的情况时,会立即ACK,该ACK的TSER部分包含的TSEV值会记录当前接收端收到有序报文段的时刻 。这会使得数据包的RTT样本值增大,进一步导致RTO时间延长 。这对TCP来说无疑是有益的,因为TCP有充分的时间判断数据包到底是失序还是丢了来防止不必要的数据重传 。当然严重的乱序则会让发送端以为是丢包一旦重复的ACK超过TCP的阈值,便会触发超时重传机制,以及时解决这种问题;
查看:抓包分析是否存在很多乱序报文:
网络编程之网络丢包故障如何定位?如何解决?

文章插图
 
解决方案:如果在多径传输场景或者网络质量不好,可以通过修改下面值来提供系统对TCP无序传送的容错率:
网络编程之网络丢包故障如何定位?如何解决?

文章插图
 
拥塞控制丢包在互联网发展的过程当中,TCP算法也做出了一定改变,先后演进了
Reno、NewReno、Cubic和Vegas,这些改进算法大体可以分为基于丢包和基于延时的拥塞控制算法 。基于丢包的拥塞控制算法以Reno、NewReno为代表,它的主要问题有Buffer bloat和长肥管道两种,基于丢包的协议拥塞控制机制是被动式的,其依据网络中的丢包事件来做网络拥塞判断 。即使网络中的负载很高,只要没有产生拥塞丢包,协议就不会主动降低自己的发送速度 。最初路由器转发出口的Buffer 是比较小的,TCP在利用时容易造成全局同步,降低带宽利用率,随后路由器厂家由于硬件成本下降不断地增加Buffer,基于丢包反馈的协议在不丢包的情况下持续占用路由器buffer,虽然提高了网络带宽的利用率,但同时也意味着发生拥塞丢包后,网络抖动性加大 。另外对于带宽和RTT都很高的长肥管道问题来说,管道中随机丢包的可能性很大,TCP的默认buffer设置比较小加上随机丢包造成的cwnd经常下折,导致带宽利用率依旧很低; BBR(Bottleneck Bandwidth and Round-trip propagation time)是一种基于带宽和延迟反馈的拥塞控制算法 。目前已经演化到第二版,是一个典型的封闭反馈系统,发送多少报文和用多快的速度发送这些报文都是在每次反馈中不断调节 。在BBR提出之前,拥塞控制都是基于事件的算法,需要通过丢包或延时事件驱动;BBR提出之后,拥塞控制是基于反馈的自主自动控制算法,对于速率的控制是由算法决定,而不由网络事件决定,BBR算法的核心是找到最大带宽(Max BW)和最小延时(Min RTT)这两个参数,最大带宽和最小延时的乘积可以得到BDP(Bandwidth Delay Product), 而BDP就是网络链路中可以存放数据的最大容量 。BDP驱动Probing State Machine得到Rate quantum和cwnd,分别设置到发送引擎中就可以解决发送速度和数据量的问题 。
Linux 4.9内核首次采用BBR拥塞控制算法第一个版本,BBR抗丢包能力比其他算法要强,但这个版本在某些场景下面有问题(缺点),BBR在实时音视频领域存在的问题,深队列竞争不过Cubic 。
问题现象就是:在深队列场景,BBR的ProbeRTT阶段只发4个包,发送速率下降太多会引发延迟加大和卡顿问题 。
查看:
ss -sti //在源端 ss -sti|grep 10.125.42.49:47699 -A 3 ( 10.125.42.49:47699 是目的端地址和端口号)
网络编程之网络丢包故障如何定位?如何解决?

文章插图
 

网络编程之网络丢包故障如何定位?如何解决?

文章插图
 
解决方案:
  • ProbeRTT并不适用实时音视频领域,因此可以选择直接去除,或者像BBRV2把probe RTT缩短到2.5s一次,使用0.5xBDP发送;
  • 如果没有特殊需求,切换成稳定的cubic算法;
UDP层丢包收发包失败丢包
查看:netstat 统计
如果有持续的 receive buffer errors/send buffer errors 计数;
网络编程之网络丢包故障如何定位?如何解决?

文章插图
 
解决方案:
  1. CPU负载(多核绑核配置),网络负载(软中断优化,调整驱动队列netdev_max_backlog),内存配置(协议栈内存);


    推荐阅读