Linux 建立 TCP 连接的超时时间分析

Linux 建立 TCP 连接的超时时间分析


概述

Linux 系统默认的建立 TCP 连接的超时时间为 127 秒,对于许多客户端来说,这个时间都太长了, 特别是当这个客户端实际上是一个服务的时候,更希望能够尽早失败,以便能够选择其它的可用服务重新尝试。

socket 是 Linux 下实现的传输控制层协议,包括 TCP 和 UDP,一个 socket 端点由 IP 和端口对来唯一标识; 如果开启了地址复用,那么可以进一步由协议,IP 和端口来唯一标识。

系统调用 connect 则是用来尝试建立 socket 连接(TCP),著名的 TCP 三次握手实际上也由 connect 来触发完成的。

超时分析

网络中的连接超时非常常见,所以连接加入了重试机制, 同时为了不给服务端带来过大的压力,重试也是有相应的策略,有一定的退避机制和重试次数。

在 Linux 中,连接超时典型为 2 分 7 秒,而对于一些 client 来说,这是一个非常长的时间; 所以在编程中,可以使用非阻塞的方式来实现,例如:使用 poll, epoll 等系统调用来实现多路复用等待。

下面来看看 2 分 7 秒是怎样来的,以及怎样配置 Linux kernel 来缩短这个超时。

2 分 7 秒
2 分 7 秒即 127 秒,刚好是 2 的 7 次方减一,对数字敏感的读者可能已经看出来了,如果 TCP 握手的 SYN 包超时重试按照 2 的幂来退避, 那么:

第 1 次发送 SYN 报文后等待 1s(2 的 0 次幂),如果超时,则重试
第 2 次发送后等待 2s(2 的 1 次幂),如果超时,则重试
第 3 次发送后等待 4s(2 的 2 次幂),如果超时,则重试
第 4 次发送后等待 8s(2 的 3 次幂),如果超时,则重试
第 5 次发送后等待 16s(2 的 4 次幂),如果超时,则重试
第 6 次发送后等待 cr(2 的 5 次幂),如果超时,则重试
第 7 次发送后等待 64s(2 的 6 次幂),如果超时,则超时失败
上面的结果刚好是 127 秒。也就是说 Linux 内核在尝试建立 TCP 连接时,最多会尝试 7 次。

超时验证

我们如何来验证呢?下面就具体和大家一起分享下:
首先,配置 iptables 来丢弃指定端口的 SYN 报文

# iptables -A INPUT --protocol tcp --dport 5000 --syn -j DROP 添加过滤

PS;别忘了用—D进行删除;需要root权限;

tcpdump,又该你上场了

# tcpdump -i lo -Ss0 -n src 127.0.0.1 and dst 127.0.0.1 and port 5000

测试:

[matrix@localhost ~]$ date; telnet 127.0.0.1 5000; date
2018年 01月 24日 星期三 22:38:15 CST
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection timed out
2018年 01月 24日 星期三 22:40:22 CST
[matrix@localhost ~]$ 


[matrix@localhost ~]$ sudo tcpdump -i lo 'tcp[tcpflags] = tcp-syn'
[sudo] password for matrix: 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
22:38:15.825569 IP localhost.54464 > localhost.commplex-main: Flags [S], seq 2345953452, win 32792, options [mss 16396,sackOK,TS val 19650917 ecr 0,nop,wscale 7], length 0
22:38:16.825246 IP localhost.54464 > localhost.commplex-main: Flags [S], seq 2345953452, win 32792, options [mss 16396,sackOK,TS val 19651917 ecr 0,nop,wscale 7], length 0
22:38:18.825139 IP localhost.54464 > localhost.commplex-main: Flags [S], seq 2345953452, win 32792, options [mss 16396,sackOK,TS val 19653917 ecr 0,nop,wscale 7], length 0
22:38:22.825095 IP localhost.54464 > localhost.commplex-main: Flags [S], seq 2345953452, win 32792, options [mss 16396,sackOK,TS val 19657917 ecr 0,nop,wscale 7], length 0
22:38:30.825387 IP localhost.54464 > localhost.commplex-main: Flags [S], seq 2345953452, win 32792, options [mss 16396,sackOK,TS val 19665917 ecr 0,nop,wscale 7], length 0
22:38:46.825921 IP localhost.54464 > localhost.commplex-main: Flags [S], seq 2345953452, win 32792, options [mss 16396,sackOK,TS val 19681918 ecr 0,nop,wscale 7], length 0
22:39:18.826499 IP localhost.54464 > localhost.commplex-main: Flags [S], seq 2345953452, win 32792, options [mss 16396,sackOK,TS val 19713918 ecr 0,nop,wscale 7], length 0

如何改进

怎样修改 connect timeout
对于很多客户端程序来说,127 秒都是一个很长的时间,特别是对于局域网来说,公司内部往往都具有网络质量较好的局域网, 访问内部的服务并不需要等待这么长的超时,而可以 fail earlier。

Linux 内核中,net.ipv4.tcp_syn_retries 表示建立 TCP 连接时 SYN 报文重试的次数,默认为 6,可以通过 sysctl 命令查看。

# sysctl -a | grep tcp_syn_retries

vim /etc/sysctl.conf
net.ipv4.tcp_syn_retries = 6
将其修改为 1,则可以将 connect 超时时间改为 3 秒,例如:
# sysctl net.ipv4.tcp_syn_retries=1
之后,sysctl -p /etc/sysctl.conf 

再次使用 telnet 验证超时时间,如下:

[matrix@localhost ~]$ date; telnet 127.0.0.1 5000; date
2018年 01月 24日 星期三 22:46:19 CST
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection timed out
2018年 01月 24日 星期三 22:46:22 CST


[matrix@localhost ~]$ sudo tcpdump -i lo 'tcp[tcpflags] = tcp-syn'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes


22:46:19.439704 IP localhost.54467 > localhost.commplex-main: Flags [S], seq 3513959316, win 32792, options [mss 16396,sackOK,TS val 20134532 ecr 0,nop,wscale 7], length 0
22:46:20.439675 IP localhost.54467 > localhost.commplex-main: Flags [S], seq 3513959316, win 32792, options [mss 16396,sackOK,TS val 20135532 ecr 0,nop,wscale 7], length 0

5 自我介绍

个人介绍:杜宝坤,京东联邦学习从0到1构建者,带领团队构建了京东的联邦学习解决方案,实现了电商营销领域支持超大规模的工业化联邦学习解决方案,支持超大规模样本PSI隐私对齐、安全的树模型与神经网络模型等众多模型,建模不受限,同时带领团队实现了业务侧的落地,开创了新的业务增长点,产生了显著的业务经济效益。

个人喜欢研究技术。基于从全链路思考与决策技术规划的考量,研究的领域比较多,从架构、大数据到机器学习算法与框架均有涉及。欢迎喜欢技术的同学和我交流,邮箱:baokun06@163.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值