文章目录

  • 一、connectTimeout
    • 应用层的超时分析
    • 内核层的超时分析
    • 综合分析
  • 二、writeTimeout
  • 三、readTimeout
  • 四、httpClient中的connectTimeout、socketTimeout、connectionRequestTimeout区别
  • 五、一些额外知识点
  • 一些资料

在实际编程中,我们会经常到超时时间这个概念。对于网络相关的超时时间,很多同学其实都只是一知半解,知其然而不知所以然。今天我们就来梳理一下网络中可能出现的各个超时时间。

一、connectTimeout

我们日常接触到的网络编程基本都是基于tcp协议的。我们都知道,两台主机需要通信需要先建立socket连接。而connectTimeout就是用来设置连接超时的。

应用层的超时分析

从字面上看,连接超时就是在一定时间内还是连接不上目标主机。在Java、python中建立socket连接其实最终都要进行系统调用进入内核态,剩下的就是等待内核通知连接建立(这里还分阻塞和非阻塞的情况,不具体展开)。所以对于Java、Python来说,如果他们自行在代码中设置了超时时间(一般是叫connectTimeout或者socketTimeout),那么这个超时时间一到如果内核还没成功建立连接,那就认为是连接超时了。如果他们没设置超时时间,那么这个connectTimeout就取决于内核什么时候抛出超时异常了。

因此,我们需要分析一下内核是怎么来判断连接超时的。

内核层的超时分析

我们都知道一个连接的建立需要经过3次握手,所以连接超时简单的说是是客户端往服务端发的SYN报文没有得到响应(服务端没有返回ACK报文)。

由于网络本身是不稳定的,丢包是很常见的事情(或者对方主机因为某些原因丢弃了该包),因此内核在发送SYN报文没有得到响应后,往往还是进行多次重试。同时,为了避免发送太多的包影响网络,重试的时间间隔还会不断增加。

在linux中,重试的时间间隔会呈指数型增长,为2的N次方,即:

  1. 第一次发送SYN报文后等待1s(2的0次幂)后再重试
  2. 第二次发送SYN报文后等待2s(2的1次幂)后再重试
  3. 第三次发送SYN报文后等待4s(2的2次幂)后再重试
  4. 第四次发送SYN报文后等待8s(2的3次幂)后再重试
  5. 第五次发送SYN报文后等待16s(2的4次幂)后再重试
  6. 第六次发送SYN报文后等待32s(2的5次幂)后再重试
  7. 第七次发送SYN报文后等待64s(2的6次幂)后再重试

对于重试次数,由linux的net.ipv4.tcp_syn_retries来确定,默认值一般是6(有些linux发行版可能不太一样),我们可以通过sysctl net.ipv4.tcp_syn_retries查看。比如重试次数是6次,那么我们可以得出超时时间应该是 1+2+4+8+16+32+64=127秒 (上面的第一条是第一次发送SYN报文,不算重试)。

如果我们想修改重试次数,可以输入命令sysctl -w net.ipv4.tcp_syn_retries=5来修改(需要root权限)。如果希望重启后生效,将net.ipv4.tcp_syn_retries = 5放入/etc/sysctl.conf中,之后执行sysctl -p 即可生效。

在一些linux发行版中,重试时间可能会变动,网上有些博客也有说重试时间分别是3s,6s,12s,24s。其他的操作系统超时时间也不一样,比如我的mac默认的超时时间为75秒。如果想确定操作系统具体的超时时间,可以通过下面这条命令来判断:

date; telnet 10.16.15.15 5000; date

综合分析

如果应用层面设置了自己的超时时间,同时内核也有自己的超时时间,那么应该以哪个为准呢?答案是哪个超时时间小以哪个为准

个人认为,在我们的实际应用中,这个超时时间不宜设置的太长,通常建议10s以内。比如在分布式系统中,我们通常会在多台节点中根据一定策略选择一台进行连接。在有机器宕机的情况下,如果连接超时时间设置的比较长,而我们客户端的线程池又比较小,就很可能大多数的线程都在等待建立连接,过了较长时间才发现连接不上,影响应用的整体吞吐量。

二、writeTimeout

在tcp连接建立之后,写操作可以理解为向对端发送tcp报文的过程。在tcp的实现中,每一段报文都需要有对端的回应,即ACK报文。和连接时发送SYN报文一样,如果超过一定时间没有收到响应,内核会再次重发该报文。和SYN报文的重试不同的是,linux有另外的参数来控制这个重试次数,即net.ipv4.tcp_retries2,可以通过sysctl net.ipv4.tcp_retries2查看其值。

另外,这个数据报文重试时间间隔的计算方式也和SYN报文不一样,由于计算方式比较复杂,这里就不详细介绍。(这其中的细节很多,具体的搜下TCP的重传机制)

一般linux发行版的net.ipv4.tcp_retries2的默认值为5或者15,对应的超时时间如下表:

tcp_retries2 对端无响应
5 25.6s-51.2s,根据动态rto定
15 924.6s-1044.6s,根据动态rto定

在Java或者python中,一般通过设置socketTimeout来达到设置写超时的目的。和SYN报文的超时时间一样,如果应用层设置了超时时间,哪么具体的超时时间以内核和应用层的超时时间的最小值为准。

三、readTimeout

在tcp协议中,读的操作和写操作的逻辑是想通的。

tcp连接建立后,两边的通信无非就是报文的互传。写操作是将数据放到tcp报文中发送给对端,然后等待对端响应,一定时间没有得到响应就是超时。而读操作其实就是发送一个读取数据的报文给对端,然后对端返回带有数据的报文,一定时间没有收到对端的报文则认为超时。对于tcp协议而言,其实不会分辨他们发送的报文具体是要干嘛,因此readTimeout的判断逻辑和writeTimeout基本一样。它的重传次数也是由参数net.ipv4.tcp_retries2控制。在应用层面也一般是统一叫socketTimeout。

四、httpClient中的connectTimeout、socketTimeout、connectionRequestTimeout区别

在Java的Httpclient库中,我们发现它可以设置3种超时时间:

  • connectTimeout:就是我们上文说的连接超时,http协议也是基于tcp的,因此在发送请求之前需要先建立tcp连接,这个connectTimeout来是用来设置连接超时的。如果设置为0,那就是由操作系统的超时时间来决定,一般建议设置在10s以内

  • socketTimeout:就是我们上文说的读超时和写超时,比如http请求要发送到对端,多久没有得到响应就算超时。

  • connectionRequestTimeout:这个超时时间就和网络无关了,主要和httpClient内部的实现有关。httpClient会维护一个连接池,由于连接池的数量有限,如果过多的客户端来获取连接,部分客户端就需要等待。这个超时时间就是表示如果客户端超过一定时间还没有从连接池获取到连接,则认为超时。

五、一些额外知识点

物理机突然宕机和进程宕掉的表现不一样。一个tcp连接建立后,如果一端的物理机突然宕机,另外一端是完全不知情的,它会像往常一样继续发送相关报文,直到超时时间到了才返回。另外,一般操作系统会有机制检测来释放该tcp连接。而如果只是进程宕掉,在进程退出的时候,操作会负责回收这个进程所属的所有tcp连接,在这时会向这些tcp连接的对端发送FIN报文,表示要关闭连接了,这时候对端是可以知道连接已经关闭的。(如果进程退出后还收到来自对端的报文,那么内核会立马发送reset给对端,从而不会卡住对端的线程资源)

一些资料

https://stackoverflow.com/questions/18184899/what-is-the-difference-between-the-setconnectiontimeout-setsotimeout-and-http

https://developer.aliyun.com/article/751558

关于网络超时时间那些事相关推荐

  1. android 设置网络超时时间设置,Android:AndroidHttpClient-如何设置超时时间?

    我已经按照kuester2000的回答进行了操作,但是我的超时设置似乎不起作用. try { int timeout = 3000; URL myURL = //some valid URL Andr ...

  2. 设置AFNetworking网络请求的超时时间

    设置AFNetworking网络请求的超时时间 也许大家使用的时候已经察觉到,设置AFNetworking的超时时间并不管用,但可以用特殊的方式来处理. 以下是笔者基于AFNetworking2.5. ...

  3. TCP 超时时间设置过长或 MTU 设置不合理会导致网络速度变慢吗

    是的,TCP 超时时间设置过长或 MTU 设置不合理都可能导致网络速度变慢. TCP 超时时间是指在发送数据之后,如果没有收到对端的应答,就会在超时时间后再次发送数据.如果超时时间设置过长,会导致发送 ...

  4. 服务器时间修改连接超时时间,服务器设置网络连接超时时间设置

    服务器设置网络连接超时时间设置 内容精选 换一换 有以下几种现象:将制作好的SD卡插入开发者板并上电后,开发者板LED1与LED2灯状态信息异常.将制作好的SD卡插入开发者板,并通过USB方式连接Ub ...

  5. 【Java 网络编程】服务器端 ServerSocket 配置 ( 端口复用 | 缓冲区设置 | 超时时间 | 性能权重 | 端口绑定 )

    文章目录 I ServerSocket 端口号绑定参数 II ServerSocket 复用绑定端口设置 III ServerSocket 设置缓冲区大小 IV ServerSocket 设置超时时间 ...

  6. 【Java 网络编程】客户端 Socket 配置 ( 超时时间 | 端口复用 | Nagle 算法 | 心跳包机制 | 连接关闭机制 | 缓冲区大小 | 性能权重设置 | 紧急数据设置 )

    文章目录 I 设置读取超时时间 II Socket 复用绑定端口设置 III 开启 Nagle 算法 ( 沾包 ) IV 心跳包机制 V 连接关闭处理 VI Socket 紧急数据内敛设置 VII S ...

  7. java测试网络延时_java测试网络连接是否成功并设置超时时间

    /** * 获取RMI接口状态 * * @return "0":服务正常,"1": 连接报错,"2":连接超时 */ @Override p ...

  8. 网络超时检测、心跳检测的方法

    在网络通信中很多操作都是默认阻塞的,比如 recv函数,当接收缓冲区中的数据没有达到水位线时,上层会一直处在阻塞等待数据就绪的状态.出现这种情况的原因有两个,一个是数据没有就绪,一个是网络连接断开. ...

  9. c#程序设定使用期限_C# 给某个方法设定执行超时时间

    在某些情况下(例如通过网络访问数据),常常不希望程序卡住而占用太多时间以至于造成界面假死. 在这时.我们可以通过Thread.Thread + Invoke(UI)或者是 delegate.Begin ...

  10. C# 给某个方法设定执行超时时间

    在某些情况下(例如通过网络访问数据),常常不希望程序卡住而占用太多时间以至于造成界面假死. 在这时.我们可以通过Thread.Thread + Invoke(UI)或者是 delegate.Begin ...

最新文章

  1. android打不开链接,安卓的webView的loadUrl打不开,太长的url超链接,求解
  2. 《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(3)--- 服务访问和配置模式...
  3. 彻底理解Intel FPGA时序约束---解决方案篇(二)
  4. 滴滴开源Android插件化框架VirtualAPK原理分析
  5. SVN:多版本库环境的搭建
  6. [PHP] 三种运行模式 ISAPI模式 APACHE2HANDLER模式 CGI模式 FastCGI模式
  7. OpenJ_Bailian 4017 爬楼梯
  8. [轉].NET项目是否有必要升级到.NET 3.5 + VS 2008
  9. foreach语句使用总结
  10. 3月4日 投影变换、仿射、Cross Ratios交比与单目测距、投影变换代码实现logo与球筐融合
  11. 【天梯选拔月赛】参与者人数(并查集模版题!remember find_father写法!)
  12. ✨✨✨【C语言】带你用最短的时间刷题(附解题思路、具体代码)不断更新(三)✨✨✨
  13. [IDEA]项目web文件夹找不到
  14. 数学作图工具_分别用于教学、排版、科研的数学作图软件
  15. Win10运行PS很卡,分享几种解决Win10用PS卡顿提速设置方法
  16. PDF编辑技巧 PDF怎么修改文字
  17. 昇腾AI室外移动机器人原理与应用(二 初识室外移动机器人)
  18. Redhat认证考试心得之一死记硬背篇
  19. linux 对设备不适当的ioctl操作,似乎对设备的直接操作只有ioctl函数了
  20. 【面向对象应用~.~】——项目开发团队分配管理软件

热门文章

  1. Freeman链码,差分码,归一化链码,归一化差分码
  2. JavaScript实现HTML导航栏下拉菜单[悬浮显示]
  3. 一文62页PPT读懂中国供应链金融
  4. 风尚云网学前端----HTML特殊字符编码对照表
  5. linux交叉编译libnet,交叉编译samba(mipsel-linux) samba-3.3.3.tar.gz
  6. 北斗一代卫星导航系统简介
  7. Radius认证协议(六)报文属性
  8. 基于51单片机的超声波测距带语音播报
  9. 学习《华为基本法》(大结局):法的修订与接班人
  10. android expandablelistview横向,ExPandableListView实现时间轴效果【Android】