02 veth对乱序包问题

一 tcp协议详解

超时重传、快重传、sack、d-sack、滑动窗口、流量控制、拥塞控制

https://egonlin.com/?p=7266

tcp协议如何实现可靠

1、序列号与确认应答,适用于网络环境正常

2、如果网络环境有延迟,会丢包,你将无法及时收到确认应答,干等着效率很低

于是有了超时重传

发一次包,收到一个确认,这个过程称之为RTT(Round-Trip Time 往返时延)

超时重传时间是以 RTO (Retransmission Timeout 超时重传时间)

超时重传时间 RTO 的值,不能过小,也不能过大,应该略大于报文往返 RTT 的值。

  • 1、当超时时间 RTO 较大时,重发就慢,丢了老半天才重发,没有效率,性能差;
  • 2、当超时时间 RTO 较小时,会导致可能并没有丢就重发,于是重发的就快,会增加网络拥塞,导致更多的超时,更多的超时导致更多的重发。

如果超时重发的数据,再次超时的时候,又需要重传的时候,TCP 的策略是超时间隔加倍。

也就是每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。

超时触发重传存在的问题是,超时周期可能相对较长。那是不是可以有更快的方式呢?

于是就可以用「快速重传」机制来解决超时重发的时间等待。

3、快重传:

所以,快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。

快速重传机制只解决了一个问题,就是超时时间的问题,但是它依然面临着另外一个问题。就是重传的时候,是重传之前的一个,还是重传所有的问题。

比如对于上面的例子,是重传 Seq2 呢?还是重传 Seq2、Seq3、Seq4、Seq5 呢?因为发送端可以发送了seq1、seq2、seq3、seq4、seq5、seq6、seq7、seq8,从seq2开始丢包了,然后假设seq3、seq4、seq5都丢了,从seq6往后才开始发送正常,但是也返回ack2,此时发送端并不清楚连续的三个 Ack 2 是谁传回来的,这时候仅重传seq2很明显是不合理的

根据 TCP 不同的实现,以上两种情况都是有可能的。可见,这是一把双刃剑。

为了解决不知道该重传哪些 TCP 报文,于是就有 SACK 方法。

4、快重传的另外一种实现机制-SACK方法

还有一种实现重传机制的方式叫:SACK( Selective Acknowledgment 选择性确认)。

这种方式需要在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将缓存的地图发送给发送方,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。

如下图,发送方收到了三次同样的 ACK 确认报文,称之为Dup Ack,于是就会触发快速重发机制,通过 SACK 信息发现只有 200~299 这段数据丢失,则重发时,就只选择了这个 TCP 段进行重复。

综上,通常情况下,发送端是要在收到了3个Dup Ack之后才会重发数据包,但在容器环境里,很多时候你会发现,发送方只收到一个Dup Ack就立马重发数据了

这是因为在linux系统中,发送方收到sack信息之后,就知道了接收方对数据的接收情况,此时发送方会接收方收到的数据与未收到的数据量差值(这个差值是根据bytes计算机而来的,而不是按照包的数据),如果该差值过大,超过了reordering*mss_cache,就会立刻重传数据,

所以,如果当发送方发送的包出现了很多乱序包的时候,就很可能造成该差值过大,导致收到一个dup ack就开始重传,从而造成大量的重传线下

nsenter -t $pid -n netstat -s |grep reordering

在容器环境里,出现乱序包+sack导致发生重传的概率要远大于因为网络丢包而产生的重传

但是需要强调的是,并非只要乱序就会重传,而是差值过大导致的重传!!!

联系管理员微信tutu19192010,注册账号

上一篇
下一篇
Copyright © 2022 Egon的知识星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术