mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-24 20:00:37 +00:00
docs: 汇编研究
This commit is contained in:
@@ -2,6 +2,147 @@
|
||||
|
||||
## TCP/UDP
|
||||
|
||||
TCP 传输的核心公式:速度 = 窗口大小/往返时间,这个公式对于理解传输本质和排查传输问题具有很强的知道意义。
|
||||
|
||||
TCP 里面有三种窗口:发送窗口、接收窗口、拥塞窗口。如果没有特别说明,TCP Window 指的是接收窗口。
|
||||
|
||||
TCP Window Full:指的是在途数据的大小等于接收窗口大小时,窗口会“满”
|
||||
|
||||
Wireshark 分析得到的信息,都会用方括号包起来,TCP 报文本身的信息,没有方括号。
|
||||
|
||||
|
||||
|
||||
### TCP 如何探测到拥塞
|
||||
|
||||
TCP 传输的起始阶段,速度都是从低到高升上来的,很少一上来就以最终速度运行的情况。
|
||||
|
||||
这个机制其实就是 TCP 的拥塞控制。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### TCP 拥塞控制
|
||||
|
||||
TCP 使用拥塞机制来确保传输速度和稳定性。拥塞机制是通信双方自己要实现的功能,在途中的网络设备(交换机、路由器)转发,不关心拥塞机制。
|
||||
|
||||
拥塞机制包括:慢启动、拥塞避免、快速重传、快速回复。
|
||||
|
||||
#### 慢启动
|
||||
|
||||
Slow start,即 TCP 传输的开始阶段是从一个相对低的速度开始的。之后拥塞窗口会翻倍方式增长。每次 TCP 收到一个确认了数据的 ACK,拥塞窗口就增加1个 MSS
|
||||
|
||||

|
||||
|
||||
当收到重复的 ACK 报文(即确认号一样),比如收到2个 ACK,但他们的确认号一样,那么第二个 ACK 就不算是“确认数据的 ACK”,拥塞窗口就不会增加2个 MSS,只会增加1个 MSS。
|
||||
|
||||
会持续增长吗?当然不是,有终止条件:
|
||||
|
||||
- 遇到了拥塞
|
||||
|
||||
- 拥塞窗口增长到慢启动阈值
|
||||
|
||||
注意:慢启动阶段,并不是“每过1RTT 就翻倍”,也可能会比翻倍少一些。什么意思呢?慢启动阶段,TCP 每收到一个 ACK,拥塞窗口就增加1MSS。假设初始拥塞窗口大小为2MSS,发送2个数据报之后:
|
||||
|
||||
- 收到1个ACK(间隔确认),那么在1RTT内,拥塞窗口从2变为3,没有翻倍
|
||||
|
||||
- 收到2个ACK,那么在1RTT内,拥塞窗口从2变为4,翻倍了
|
||||
|
||||
#### 慢启动阈值
|
||||
|
||||
**慢启动阈值** ssthresh,过了这个阈值,拥塞窗口的增长速度就立刻变慢了,变为每过一个 RTT,拥塞窗口就增加一个 MSS(之前是没收到一个确认数据的 ACK 就增加1个 MSS)
|
||||
|
||||

|
||||
|
||||
上图所示,假设 ICW 是4个 MSS,ssthresh 是32个 MSS,慢启动阶段经过1个 RTT 后,CW 扩大为8MSS、16MSS、32MSS。等到了阈值之后,TCP就进入拥塞避免阶段了。每过一个 RTT,拥塞窗口只增加1MSS,曲线就变为较为斜率较低的直线了。
|
||||
|
||||

|
||||
|
||||
QA:如果拥塞窗口大小正好等于慢启动阈值,那么发送方这时候是需要采用拥塞避免过程(线性增长)还是继续选择慢启动过程(指数增长)?[RFC5681](https://datatracker.ietf.org/doc/html/rfc5681) 规定是说两者都可以。
|
||||
|
||||
#### 间隔确认
|
||||
|
||||
很多 TCP 的实现中,如果收到连续多个报文,确认报文是间隔一个进行回复的。
|
||||
|
||||
比如:发送方发送1、2,接收方收到1、2,此时针对2进行确认。发送方发送3、4,接收方针对4进行确认。这样的机制下,会使得拥塞窗口的增长速度,比每次 ACK 更低一些(更稳)
|
||||
|
||||
#### 拥塞窗口
|
||||
|
||||
Congestion Window,拥塞窗口,简写 CW。拥塞窗口是针对每个连接进行维护的,比如某个主机有3个 TCP 连接在传输数据,那么这3个连接就各自维护自己的拥塞窗口。
|
||||
|
||||
**初始化拥塞窗口**,Initial Congestion Window,简写为 ICW(IW)。
|
||||
|
||||
在 Linux 内核3.0以前,ICW 的比较小,在2到4个MSS,2010年谷歌提出,为了充分利用现代互联网的传输能力,Linux 应该把 ICW 从2~4个MSS提升到10MSS。这也被应用到 Linux 内核3.0及其以后的版本中规定了 `TCP_INIT_CWND` 为10.
|
||||
|
||||
```c
|
||||
#define TCP_INIT_CWND 10
|
||||
```
|
||||
|
||||
这个值在慢启动阶段影响了传输速度,慢启动阶段每经过1个RTT,拥塞窗口就翻倍,所以不同的 ICW 就会造成不同的传输速度。
|
||||
|
||||
| ICW | 1RTT后 | 2RTT后 | 3RTT后 |
|
||||
| --- | ----- | ----- | ----- |
|
||||
| 2 | 4 | 8 | 16 |
|
||||
| 10 | 20 | 40 | 80 |
|
||||
|
||||
#### 拥塞避免
|
||||
|
||||
TCP 野蛮生长后当达到慢启动阈值之后,会进入拥塞避免阶段。这个阶段的特点是“和性增长乘性降低”(Addictive increase/multiplicative decrease,AIMD),解释下就是拥塞避免阶段每个RTT时间,拥塞窗口只增长1MSS,这个阶段的拥塞窗口增长是线性的(斜率比较低的直线),当探测到拥塞时,拥塞窗口就要往下降,下降是直接减半的,叫做乘性降低。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 窗口和 MSS 的关系
|
||||
|
||||
窗口一般比MSS大,MSS 是有确定上限的,一般为1460,当然实际情况下值可能更低。
|
||||
|
||||
窗口一般是n个MSS。
|
||||
|
||||
|
||||
|
||||
#### 快速重传
|
||||
|
||||
TCP 每发送一个报文,就会启动一个超时计时器,若在限定时间内没有收到这个报文的确认,则发送方认为这个报文在网络上丢了,需要发送方重传这个报文,这个机制叫做“超时重传”。
|
||||
|
||||
TCP 最小超时重传时间为200ms,在这个机制下虽然解决了丢包问题,但带来一个新的问题:某个包都已经丢失了,还需要等待200ms或者更长时间,那体验不就更糟糕了吗?
|
||||
|
||||
TCP 会利用另一种机制来解决超时重传带来的时间等待问题,就是快速重传机制,一旦发送方收到3次重复确认(确认 ACK 报文中有确认号)加上第一次确认就一共4次,就不用等待超时计时器了,直接重传这个报文。
|
||||
|
||||
注意:快速重传看的是数据,超时重传看的是时间。
|
||||
|
||||
#### 快速恢复
|
||||
|
||||
快速恢复是 TCP Reno 算法引入的一个阶段,是和“快速重传”搭配工作的。跟之前的“慢启动-拥塞避免-慢启动-拥塞避免”不同的是,当遇到拥塞点之后,通过快速重传,就不再进入慢启动了,而是从这个减半的拥塞窗口开始,保持跟拥塞避免一样的线性增长,直到遇到下一个拥塞点。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
注意:“快速恢复”有几个小细节
|
||||
|
||||
- 快速恢复一定是和快速重传搭配使用的。那有何表现或者为什么这么设计?如果在快速重传的场景下(也就是收到连续3次重复确认 ACK 报文),那么这个特征可以理解为“网络虽然有点问题,但是能收到3次重复 ACK 报文,网络也没那么糟糕”,所以如果走传统的拥塞避免直接从0开始就很慢也很浪费效率,但如果按照拥塞避免直接减半之后再走慢启动,也很浪费网络,所以当遇到一个拥塞点之后,减半就按照拥塞避免(线性增长)。
|
||||
|
||||
|
||||
|
||||
总结:慢启动不只是在 TCP 连接启动的阶段才发生,传输的过程中遇到网络较差也会发生多次慢启动。一旦拥塞避免阶段探测到了拥塞,TCP 还是会回到慢启动过程,只不过这个慢启动阈值跟之前的不同,如果有多次拥塞,会重复这个过程直到传输结束。
|
||||
|
||||
### 总结
|
||||
|
||||
- 慢启动:每收到一个 ACK,拥塞窗口(CW)增加一个 MSS
|
||||
|
||||
- 拥塞避免:策略是“和性增长乘性降低”,每一个 RTT,CW 增加一个 MSS
|
||||
|
||||
- 快速重传:接收到 3 次或者以上的重复确认后,直接重传这个丢失的报文
|
||||
|
||||
- 快速恢复:结合快速重传,在遇到拥塞点后,跳过慢启动阶段,进入线性增长
|
||||
|
||||
拥塞窗口(CW)和接收窗口(RW)是如何决定了传输速度上限的,简单来说:
|
||||
|
||||
- 当 RW > CW 时,速度由 CW 决定
|
||||
|
||||
- 当 RW < CW 时,速度由 RW 决定
|
||||
|
||||
## HTTP 缓存控制
|
||||
|
||||
缓存(Cache)是计算机领域里的一个重要概念,是优化系统性能的利器。
|
||||
@@ -455,9 +596,6 @@ TLS 是建立在 TCP 的上层协议,因此要先按照 TCP 的规则来,也
|
||||
|
||||
注意这里不是 TCP Fast Open,TFO 是用来加速连续 TCP 连接的数据交互 TCP 拓展协议。原理如下:TCP 三次握手的过程中,当用户首次访问 Server 时,发送 SYN 包,Server 根据用户 IP 生成 Cookie(已加密),并与 SYN-ACK 一同发回 Client;当 Client 随后重连时,在SYN 包携带 TCP Cookie;如果 Server 校验合法,则在用户回复 ACK 前就可以直接发送数据;否则按照正常三次握手进行。
|
||||
|
||||
|
||||
|
||||
|
||||
第三步:服务器会把证书也发送给客户端(Server Certificate),见下图第一个大红框中的内容。
|
||||
|
||||
同时服务器选择了 ECDHE 算法,所以在发送了服务器证书后马上发送“Server Key Exchange”消息。里面是椭圆曲线的公钥(Server Params),用来实现密钥的交换算法,再加上自己的私钥签名认证(用私钥对椭圆曲线的 public key 做了签名认证生成了 Signature)
|
||||
|
||||
Reference in New Issue
Block a user