转自:https://huoding.com/2017/08/13/628

前两天,我在微博上推荐了一篇朝花夕拾的文章:The story of one latency spike,文章中介绍了 cloudflare 工程师如何一步一步 debug 网络延迟问题,细细读来受益良多,不过我并不打算详细介绍那篇文章的细枝末节, 本文只摘录一个点:

When debugging network problems the delays of 1s, 30s are very characteristic. They may indicate packet loss since the SYN packets are usually retransmitted at times 1s, 3s, 7s, 15, 31s.

为什么是 1 秒、3 秒、7 秒、15 秒、31 秒?说来惭愧,我以前从没有注意过 SYN 重建时的时间特征,知耻而后勇,正好借此机会来一探究竟。

下面让我们通过一个实验来重现一下 SYN 超时重传的现象:

  1. 在服务端屏蔽请求:「iptables -A INPUT –dport 1234 –syn -j DROP」
  2. 在服务端监听 1234 端口:「nc -l 1234」
  3. 在客户端开启抓包:「tcpdump -nn -i any port 1234」
  4. 在客户端发起请求:「date; nc <SERVER> 1234; date」

经过一段时间的等待后,我们可以看到 tcpdump 输出如下:

12:53:15.511826 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:16.511042 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:18.511058 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:22.511042 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:30.511065 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:46.511068 IP CLIENT.53384 > SERVER.1234: Flags [S], ...

第一行是正常发出的 SYN,后面五行是超时重传发出的 SYN,相对于正常发出的 SYN,它们的延迟分别是:1 秒、3 秒、7 秒、15 秒、31 秒,正好符合开头的描述。之所以重传五次是因为 net.ipv4.tcp_syn_retries 的缺省值是 5。

此外,我们可以看到两次 date 命令输出的时间如下:

Sun Aug 13 12:53:15 CST 2017
Sun Aug 13 12:54:18 CST 2017

可见整个握手过程从开始到超时一共持续了 63 秒,其中 31 秒是总计五次 SYN 发送的时间,剩下的 32 秒是确认第五次 SYN 超时的时间(2 的 5 次方)。由此可见,在 TCP 握手阶段一旦出现丢包,网络延迟会非常久,很多时候这是没有必要的,比如 Web 服务器,可以考虑设置 net.ipv4.tcp_syn_retries 为 2 或者 3 比较合适。

如果要获取更为明确的证据,我们还需要了解 RTO(retransmission timeout),即超时重传时间,具体计算方法很复杂,我就不多说了,有兴趣的可以参考本文解决的推荐链接,你只要知道系统会根据网络连接的情况动态调整该值的大小即可。不过在 SYN 握手阶段,网络连接还没有建立起来,如果此时发生丢包,那么因为系统没有可以参照的 RTT(Round-Trip Time),所以此时只能给出系统缺省设置的 RTO:

#define TCP_RTO_MAX	((unsigned)(120*HZ))
#define TCP_RTO_MIN ((unsigned)(HZ/5))
#define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) ... unsigned long timeo; if (req->num_timeout++ == 0)
atomic_dec(&queue->young);
timeo = min(TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX);
mod_timer(&req->rsk_timer, jiffies + timeo);
return;

可见 RTO 的最大值是 120 秒,最小值是 200 毫秒,在连接建立前的初始值是 1 秒,如果经过多次重传,每次 RTO 的值翻倍,但最大不得超过 120 秒:

  1. 第 1 次重传:2 的 0 次方,也就是 1 秒(延迟:1 秒)。
  2. 第 2 次重传:2 的 1 次方,也就是 2 秒(延迟:1 + 2 = 3 秒)。
  3. 第 3 次重传:2 的 2 次方,也就是 4 秒(延迟:3 + 4 = 7 秒)。
  4. 第 4 次重传:2 的 3 次方,也就是 8 秒(延迟:7 + 8 = 15 秒)。
  5. 第 5 次重传:2 的 4 次方,也就是 16 秒(延迟:15 + 16 = 31 秒)。

顺便说一句,在建立连接后,因为目前大部分网络都很快,所以大部分连接的 RTO 都会接近 TCP_RTO_MIN,也就是 200ms,可以通过「ss -int」命令来确认。

SYN 和 RTO的更多相关文章

  1. SYN Cookie的原理和实现

          本文主要内容:SYN Cookie的原理,以及它的内核实现. 内核版本:3.6 SYN Flood 下面这段介绍引用自[1]. SYN Flood是一种非常危险而常见的Dos攻击方式.到目 ...

  2. TCP连接建立系列 — 客户端发送SYN段

    主要内容:客户端调用connect()时的TCP层实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd connect的TCP层实现 SOCK_STRE ...

  3. [httpd] httpd server 在低负载的情况下对SYN无响应

    如题: 两台client通过load balance访问httpd server.两个client交互访问.load balance处于fullnat模式. server在低负载情况下,常常对某一个c ...

  4. TCP系列13—重传—3、协议中RTO计算和RTO定时器维护

    从上一篇示例中我们可以看到在TCP中有一个重要的过程就是决定何时进行超时重传,也就是RTO的计算更新.由于网络状况可能会受到路由变化.网络负载等因素的影响,因此RTO也必须跟随网络状况动态更新.如果T ...

  5. linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查(转载)

    linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查 一:背景:一台机器从公司办公网登录不上且所有tcp端口都telnet不通,但是通过同机房同的其它机器却可以正常访问到出问 ...

  6. TCP中RTT的测量和RTO的计算

    https://blog.csdn.net/zhangskd/article/details/7196707 tcp传输往返时间是指:发送方发送tcp断开时, 到发送方接收到改段立即响应的所耗费的时间 ...

  7. TCP三次握手中SYN,ACK,seq ack的含义

    转至:https://www.cnblogs.com/muyi23333/articles/13841268.html 1.TCP 为什么三次握手而不是两次握手 1.防止已失效的连接请求又传送到服务器 ...

  8. SYN Flood测试

    由于工作需要对公司进行SYN Flood测试,在网上查了些资料,Youtube上找到最多的方法就是hping3工具来实现, 该工具已经预装在Kali下,具体操作用一条命令即可实现. hping3 -S ...

  9. TCP的状态 (SYN, FIN, ACK, PSH, RST, URG)

    状态说明 SYN表示建立连接, FIN表示关闭连接, ACK表示响应, PSH表示有 DATA数据传输, RST表示连接重置. 其中,ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同 ...

随机推荐

  1. [转]十五天精通WCF——第五天 你需要了解的三个小技巧

    一: 服务是端点的集合 当你在开发wcf的时候,你或许已经注意到了一个service可以公布多个endpoint,确实是这样,在wcf中有一句很经典的话,叫做“服务是端点的集合",就 比如说 ...

  2. 动态加入的HTML的自己主动渲染

    这两天在写一个用EasyUI的前台,遇到动态向Layout加入HTML内容时没有自己主动渲染的问题.查了一下网上的资料后得以解决.详细例如以下: $("#content").htm ...

  3. 小胖说事14--------IOS字体大小,字号的问题 PX转化为UIFont

    PX和Font之间相互转换公示表: 计算公式为:font=(像素PX)/(96/72).

  4. 怎样给你的Android 安装文件(APK)瘦身

    本文源地址:怎样给你的Android 安装文件(APK)瘦身 Android的apk文件越来越大了这已经是一个不争的事实. 在Android 还是最初版本号的时候,一个app的apk文件大小也还仅仅有 ...

  5. $().attr()的使用方法 &amp;&amp; $().html()与$().text()的差别

    <1>$().attr()的使用方法 </pre><pre class="html" name="code"><htm ...

  6. 欢聚时代校园招聘java开发一面经历

    收到yy短信通知笔试通过后隔天就一面了,面试时间是下午1点半,跟另外一个同学在1点半的时候已经到了目的酒店,发现面试都集中在一个大厅,摆了非常多桌椅,由不同的面试关在面试.等到2点多的时候才到我.先说 ...

  7. 移植DirectFB于SOC3210(龙芯)【转】

    本文转载自:http://blog.chinaunix.net/uid-25298908-id-120188.html 编译平台:龙芯.中标普华Linux桌面5 目标平台:SOC3210 一.获取源码 ...

  8. WinForm中的ListBox组件编程

    ListBox组件是一个程序设计中经常使用到的组件,在Visual C#和Visual Basic .Net程序中使用这个组件,必须要在程序中导入.Net FrameWork SDK中名称空间Syst ...

  9. bzoj4034 [HAOI2015]树上操作——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4034 树剖裸题: 一定要注意 long long !!! update 的时候别忘了 pus ...

  10. 0503 php中for与foreach的区别

    结论: foreach:只能用于数组和对象,如果是非索引数组,只可以用foreach. for:如果是索引数组,可以用for遍历. foreach循环结构是按照数组内部的指针去循环的,当 foreac ...