为何要设置HTTP timeout?

先看一个不设置timeout形成的线上事故。网络

一次线上事故

有一次生产上的一个服务出了点故障,一个本来每5分钟执行一次的定时任务忽然不执行了。第一反应是任务执行报错,查看日志,却没有找到任何异常报错信息。工具

但经过日志能够肯定的是,该任务线程还在执行中。按照这个定时任务执行的业务逻辑来讲,这是不正常的,除了一个HTTP请求外,其它都是不耗时的操做。那么问题只多是出在HTTP请求之上了。性能

经过jstack查看线程的堆栈信息,肯定了就是HTTP请求的问题了。spa

从上面的堆栈信息,能够看到该定时任务线程处于“RUNNABLE”状态,在JVM中"RUNNABLE"表示线程运行在JVM中,但在等待操做系统的其余资源。从堆栈信息中看到,该线程正在进行Socket的读取操做。操作系统

从发现任务执行,到定位到这里,已通过去十几分钟了,Socket一直在读取等待中,说明没有设置超时时间,或者说超时时间没有生效。计算机网络

回头看程序代码,发现这个服务的HTTP工具类没有设置HTTP timeout。随后,赶忙设置timeout。线程

总结

一般健壮的程序都是要设置超时时间的,上面的程序没有设置超时时间,能够说是一段有缺陷的代码。但是这样一段有缺陷的代码,为何能在生产环境跑了好久,最后才暴露出问题呢?日志

我想主要是由于,即便你不设置超时时间,在正常状况下,一个HTTP请求老是会返回结果,即便可能会耗时较长。对于一个负载不高的服务来讲,潜在的问题没有暴露出来。接口

那么什么状况下,没有设置超时时间会形成严重的影响呢?资源

  1. 与用户操做相关的接口,若是不设置超时时间,将会出现长时间的无响应,严重影响用户体验。
  2. 负载很高的系统,由于大量调用耗时长的接口,致使性能急剧降低,从而影响其余正常的业务。
  3. 某些状况下,HTTP请求可能永远都得不到响应,那么这部分系统资源就一直被占用,直到系统奔溃。

前面两种状况比较好理解,问题是什么状况下,HTTP请求会永远得不到响应呢?

了解计算机网络应该都知道TCP创建链接时的三次握手和断开链接时的四次挥手。

TCP在断开链接时,若是出现异常状况,致使TCP链接的一端异常奔溃,好比电源掉电、系统奔溃、网络故障等。

在这种状况下,TCP的断开操做不会通知对端程序,从而致使对端程序一直处于等待状态,Socket不能及时释放。这种一端开着,一端已经关闭的状态,被称为半开链接。

回顾上面的生产故障,它恰好就是处于“半开链接”的状态,致使任务线程一直在等待响应结果。为了不这种状况的发生,超时时间是必需要设置的。

相关文章
相关标签/搜索