• 为什么要设置HTTP timeout?


    先看一个不设置timeout造成的线上事故。

    一次线上事故

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

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

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

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

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

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

    总结

    通常健壮的程序都是要设置超时时间的,上面的程序没有设置超时时间,可以说是一段有缺陷的代码。可是这样一段有缺陷的代码,为什么能在生产环境跑了很久,最后才暴露出问题呢?

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

    那么什么情况下,没有设置超时时间会造成严重的影响呢?

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

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

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

    TCP在断开连接时,如果出现异常情况,导致TCP连接的一端异常奔溃,比如电源掉电、系统奔溃、网络故障等。

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

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

  • 相关阅读:
    时间工具类
    BEANUTIL 对象转JSON
    BeanUtil 对象转json
    导入jsp
    导入Excel加行公式和验证
    导入Excel
    导出Excel
    时间工具类
    python 装饰器的详细理解【多次实验】
    Python 爬虫 ajax爬取马云爸爸微博内容
  • 原文地址:https://www.cnblogs.com/bluemilk/p/10292232.html
Copyright © 2020-2023  润新知