彻底理解connection timeout
我们在connect时常常遇到connection timeout这种错误, 如果你仔细去观察,会发现connect timout分两种情况,
Caused by: java.net.ConnectException: Operation timed out (Connection timed out)
另外一种是:
Caused by: java.net.SocketTimeoutException: connect timed out
那这两种 timeout 有什么区别?分别在什么情况下会发生?
首先无论是哪种语言,不管是客户端还是服务端,在 TCP 编程中通常都可以为 sock 设置一个 timeout 时间。而这个 timeout 又可以细分为 connect timeout、read timeout、write timeout。read timeout 和 write timeout 必须是在 connect 之后才能发生,今天不做过多讨论。上面那两种 timeout 均属于 connect timeout。
另外我们需要补充下 TCP 重传机制的相关知识:
我们知道在 TCP 的三次握手中,Client 发送 SYN,Server 收到之后回 SYN_ACK,接着 Client 再回 ACK,这时 Client 便完成了 connect() 调用,进入 ESTAB 状态。如果 Client 发送 SYN 之后,由于网络原因或者其他问题没有收到 Server 的 SYN_ACK,那么这时 Client 便会重传 SYN。重传的次数由内核参数 net.ipv4.tcp_syn_retries 控制,重传的间隔为 [1,3,7,15,31]s 等
如果 Client 重传完所有 SYN 之后依然没有收到 SYN_ACK,那么这时 connect() 调用便会抛出 connection timeout 错误。如果 Client 在重传 SYN 期间,Client 的 sock timeout 时间到了,那么这时 connect() 会抛出 timeout 错误。
理解net.ipv4.tcp_syn_retries设置
- net.ipv4.tcp_syn_retries 的设置,表示应用程序进行connect()系统调用时,在对方不返回SYN + ACK的情况下(也就是超时的情况下),第一次发送之后,内核最多重试几次发送SYN包;并且决定了等待时间.
- Linux上的默认值是 net.ipv4.tcp_syn_retries = 6 ,也就是说如果是本机主动发起连接,(即主动开启TCP三次握手中的第一个SYN包),如果一直收不到对方返回SYN + ACK ,那么应用程序最大的超时时间就是127秒
Linux 系统默认的建立 TCP 连接的超时时间为 127 秒,对于许多客户端来说,这个时间都太长了, 特别是当这个客户端实际上是一个服务的时候,更希望能够尽早失败,以便能够选择其它的可用服务重新尝试。
socket对象是Linux下应用程序需要用到的和远端建立TCP或者UDP连接的对象.
系统调用 connect(2) 则是用来尝试建立 socket 连接(TCP)的函数。 connect 对于 UDP 来说并不是必须的,而对于 TCP 来说则是一个必须过程,著名的 TCP 3 次握手实际上也由 connect 来完成。
网络中的连接超时非常常见,不管是广域网还是局域网,为了一定程度上容忍失败,所以连接加入了重试机制, 而另一方面,为了不给服务端带来过大的压力,重试也是有限制的。
在 Linux 中,连接超时典型为 2 分 7 秒,而对于一些 client 来说,这是一个非常长的时间;
下面来看看 2 分 7 秒是怎样来的,以及怎样配置 Linux kernel 来缩短这个超时。
2 分 7 秒即 127 秒,刚好是 2 的 7 次方减一,聪明的读者可能已经看出来了,如果 TCP 握手的 SYN 包超时重试按照 2 的幂来 backoff, 那么:
第 1 次发送 SYN 报文后等待 1s(2 的 0 次幂),如果超时,则重试
第 2 次发送后等待 2s(2 的 1 次幂),如果超时,则重试
第 3 次发送后等待 4s(2 的 2 次幂),如果超时,则重试
第 4 次发送后等待 8s(2 的 3 次幂),如果超时,则重试
第 5 次发送后等待 16s(2 的 4 次幂),如果超时,则重试
第 6 次发送后等待 32s(2 的 5 次幂),如果超时,则重试
第 7 次发送后等待 64s(2 的 6 次幂),如果超时,则超时失败
上面的结果刚好是 127 秒。也就是说 Linux 内核在尝试建立 TCP 连接时,最多会尝试 7 次。
接下来,我们用实验来进行验证:
首先,配置 iptables 来丢弃指定端口的 SYN 报文
# iptables -A INPUT --protocol tcp --dport 5000 --syn -j DROP
然后,打开 tcpdump 观察到达指定端口的报文
# tcpdump -i lo -Ss0 -n src 127.0.0.1 and dst 127.0.0.1 and port 5000
最后,使用 telnet 连接指定端口
date '+ %F %T'; telnet 127.0.0.1 5000; date '+ %F %T';
从tcpdump的输出也可以看到,一共发了7次SYN包(都是同一个seq号码),第一次是正常请求,后面6次是重试,正是该内核参数 设置的值.
怎样修改 connect timeout
Linux 内核中,net.ipv4.tcp_syn_retries 表示建立 TCP 连接时 SYN 报文重试的次数,默认为 6,可以通过 sysctl 命令查看。
# sysctl -a | grep tcp_syn_retries
net.ipv4.tcp_syn_retries = 6
将其修改为 1,则可以将 connect 超时时间改为 3 秒,例如:
# sysctl net.ipv4.tcp_syn_retries=1
date; telnet 127.0.0.1 5000; date;
2020年 06月 19日 星期五 22:16:11 CST
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection timed out
2020年 06月 19日 星期五 22:16:14 CST
注意:sysctl 修改的内核参数在系统重启后失效,如果需要持久化,可以修改系统配置文件,例如:,对于 CentOS 7 来说,添加 net.ipv4.tcp_syn_retries = 1 到 /etc/sysctl.conf 中即可。
应用层真正的超时时间
那么问题来了,应用层真正的超时时间一定是127秒吗?还是不能大于127秒. 通过上面的实验,基本可以得知应用层的超时间一定不能大于内核的设定. 如果应用层的设定小于内核的设定呢?超时时间应该是小于127秒的.我们继续通过实验来验证下.
现在我的机器上,内核参数是net.ipv4.tcp_syn_retries=6,最大超时时间是 127秒 应用层代码如下:
#!/usr/bin/python
import socket
from datetime import datetime
fmt = "%Y-%m-%d %H:%M:%S"
address = ('127.0.0.1',5000)
s = socket.socket()
s.settimeout(5) #设置socket超时时间为5秒
print datetime.now().strftime(fmt)
s.connect_ex(address)
print datetime.now().strftime(fmt)
我们再来观察下应用程序的表现和tcpdump的输出
python test_socket_connect_timeout.py
2020-06-19 22:10:32
2020-06-19 22:10:37
image.png
从tcpdump的输出看到,第一次发送之后,只尝试了2次重试(2的0次+2的1次),因为第三次重试要等2的2次方秒,也就是4秒, 前面1+2 + 4是7秒,而应用层设置的超时时间是5秒,介于2~3之间,因此第三次重试不会进行. 如果应用程序设置的超时时间足够长,那么第三次重试应该在22:10:39进行.
小结
- net.ipv4.tcp_syn_retries是用于设置主动发起TCP连接超时时,SYN包的重试次数,该参数如果是x,那么connect(2)调用最大的超时时间为2的x次方 -1,单位是秒.
- 应用程序最大的超时时间不能超过内核的设定,可以小于等于内核的设定.
ps: 对 TCP 协议栈的理解总是需要慢慢积累
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
彻底理解connection timeout相关推荐
- yum 报错:centos yum (28, 'Connection time-out') Trying other mirror.
问题: 在本地的虚拟机使用yum安装软件时,经常出现 centos yum (28, 'Connection time-out') Trying other mirror. 或下面的那样情况imeou ...
- 解决Genymotion下载设备失败的方法(Connection Timeout)
一直下载不下来,报错. 解决办法: 打开 C:\Users\用户名\AppData\Local\Genymobile目录 打开genymotion.log文件,在里面最下面几行,找到如下日志 [Deb ...
- linux上TCP connection timeout的原因查找
linux上TCP connection timeout的原因查找 好久没有写文章了, 今天解决了一个网络连接超时的问题, 记录以备查看. 最近在线上nginx经常出现输出connection tim ...
- Connection Timeout 问题排查
背景 我们组开发维护了一个 Agent 工程,帮客户采集一些客户有用的网络数据.客户需要下载一个 MSI,然后安装并注册. 问题描述 某个客户下载安装 Agent 之后,提示注册失败.其实 Agent ...
- 绝地求生国际服请求超时服务器未响应,绝地求生connection timeout 3.6.7解决方法/游戏连接超时怎么办...
绝地求生游戏中有很多的玩家遇到了connection timeout 3.6.7,这是怎么回事呢?下面游戏吧小编为大家带来绝地求生connection timeout 3.6.7解决方法,感兴趣的小伙 ...
- Connection Timeout和Command Timeout
每次对数据库连接时,我们有时候会碰到连接超时或者命令超时,这两个超时是不一样的.以ADO.NET为例,当客户端和服务器端连接时,碰到的超时情况主要有下面几种: 当从连接池获取一个连接时,碰到超时. 当 ...
- java jedispool实例_Jedis出现connection timeout问题解决方法(JedisPool连接池使用实例)...
今天发现jedis 默认的连接方式 jedis=new jedis("localhost",6379),老是发生connection timeout. 后来发现jedis类包还有一 ...
- IDbConnection的connection timeout 和 IDbcommand.commandTimeout
郁闷,那天,程序出错,只是简单的判断是某个存储过程执行时间太长,没在意就发给了客户, 谁知道很多都出现time out or server no responding 的错误,还以为是sql conn ...
- get connection timeout retry : 1
错误一:get connection timeout retry : 1 https://github.com/alibaba/druid/issues/4326 生产环境运行一段时间后,报错如下: ...
- 关于Flash Player 10 socket connection timeout
转载请注明,来自:http://blog.csdn.net/skyman_2001 今天我在调试游戏的时候,发现一个有趣的现象,就是flash连接上服务器后,服务器关闭连接,flash会触发secur ...
最新文章
- Blender赛车动画制作学习教程 Learn Race Car Animation with Blender
- VelocityTracker简单介绍
- Mule学习笔记(二)
- 2020年度盘点出炉!技术好文一口气读完
- 【小题目】输入两个数字以及一个符号,输出这两个数字在这个符号下运算产生的结果
- 论文小综 | Pre-training on Graphs
- 一加神秘新机入网:搭载天玑8100 首发长寿版150W超级闪充
- 【分享】林清玄:有品质的生活,从来都不是钱决定的
- Linux下DNS服务器的基本搭建
- python编程练习:漏洞百出的四则运算器
- IDEA如何设置背景色?
- Android优雅地判断软键盘弹出状态
- 碧海威 L7多款产品 后台命令执行漏洞
- Microsoft Excel 教程:如何在 Excel 中自动填充数据?
- Vue中使用Font Awesome
- 放弃40 万年薪从字节裸辞,告别 996 拥抱 955…
- java.sql.SQLException: Streaming result set com.mysql.jdbc.RowDataDynamic@44f16719 is still active.
- Fortran学习3:控制流2:循环
- Python中turtle画n层m个不同方向的圆,送你一朵小黄花
- 【机器人学】基于PoE模型的串联机械臂UR5的正运动学、微分运动学和逆运动学
热门文章
- 音乐格式转换软件测试工资,无损音乐如何转换 无损音乐格式转换 无损音乐转换器...
- 寻梦港家政上门服务小程序微擎
- 新西兰梅西大学有计算机专业吗,新西兰大学计算机排名第一之梅西大学计算机专业...
- PLC可编程控制实验装置及单片机综合实验台
- 集成App Linking服务后无法正确跳转到应用的解决方案
- 2021-11-15求积分面积和旋转体积的二重积分方法
- 2021年下半年市场营销案例分析集锦
- 用Nodejs爬取Matrix67的博客
- 场外期权:一个你从未了解过的金融衍生品市场正在中国悄悄壮大
- 机器人计算机技术,机器人技术与应用