先看一个不设置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不能及时释放。这种一端开着,一端已经关闭的状态,被称为半开连接。

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

为什么要设置HTTP timeout?的更多相关文章

  1. 【BASIS系列】SAP 设置系统timeout时间

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[BASIS系列]SAP 设置系统timeout ...

  2. 项目server中设置session timeout遇到的问题

    RT:在项目server中的web.xml设置session timeout=10,当10分钟后,继续右键执行jsp文件,运行失败,如下图所示: 但是单独启动tomcat server后,在浏览器中输 ...

  3. Cloudservice程序设置Idle timeout

    部署的云服务程序,默认的idle timeout是4分钟,意味着如果你通过一个workerrole发布了wcf服务,客户端第一次调用服务方法后,再过4分钟尝试去重新调用服务,会报错,具体测试如下: 1 ...

  4. 设置请求timeout超时

    import requests r = requests.get("http://www.cnblogs.com/yoyoketang/", timeout=1) # 设置超时 p ...

  5. Apache HttpAsyncClient 如何设置per request timeout

    最近做一个项目时用到HttpAsyncClient:因项目所需,要求能对一个具体的request 设置连接和读写超时:但发现在HttpAsyncClient中,只有在创建一个HttpAsyncClie ...

  6. urllib的实现---timeout,获取http响应码,重定向,proxy的设置

    1.Timeout设置超时 只能修改Socket设置全局Timeout #! /usr/bin/env python3 import socket import urllib.request # ti ...

  7. python socket timeout设置

    需要在调用socket的connect方法之前设置settimeout(time)方法,另外在设置之后要将再次调用settimeout(None)来设置socket进入阻塞模式. 如下代码示例: so ...

  8. nginx长连接设置

    http { keepalive_timeout 20; --长连接timeout keepalive_requests 8192; --每个连接最大请求数} events { worker_conn ...

  9. asp.net web.config 设置Session过期时间

    在Asp.net中,可以有四处设置Session的过期时间:(原文作者:望月狼地址:http://www.cnblogs.com/wangyuelang0526/) 一.全局网站(即服务器)级 IIS ...

随机推荐

  1. VueX(vue状态管理)简单小实例

    VueX:状态管理 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 核心模块:State. ...

  2. 【GStreamer开发】GStreamer播放教程08——视频解码的硬件加速

    目标 视频的硬件解码近来发展非常快速,尤其是在低功耗的设备上.本教程会讲述一些硬件加速的背景知识并解释一下GStreamer是怎么做的. 悄悄告诉你,如果设置正确地话,我们什么也不用做,GStream ...

  3. flask 编码问题

    在我们的flask项目中,通过表单提交对数据库进行更新的时候,数据提交不成功,提示以下内容: sqlalchemy.exc.InternalError: (pymysql.err.InternalEr ...

  4. a标签添加移除事件及开启禁用事件

    一.添加移除点击事件 <script type="text/javascript" src="jquery.min.js"></script& ...

  5. [转帖]QC 和 PD:关于你所不知道的快充

    QC 和 PD:关于你所不知道的快充 http://www.sohu.com/a/276214250_465976 2018-11-18 06:02 当我们使用支持 PD 或者 QC 快充协议的电源适 ...

  6. java面向函数编程简单应用

    import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.functio ...

  7. 文件类型分类:头文件dirent.h中定义的文件类型与linux内文件符号对应关系

    头文件 dirent.h 定义了文件类型: enum{    DT_UNKNOWN = 0,         //未知类型    DT_FIFO = 1,            //first in, ...

  8. windows 下搭建go开发环境

    下载golang安装包: 步骤一: 先打开环境变量配置的界面 步骤二;配置我们的环境变量 对上图的一个说明: 1).path这个变量不需要再创建,因为系统本就有,在后面添加即可. 2).增加Go的bi ...

  9. SAS学习笔记52 Excel导入后日期错乱

    读入Excel数据到SAS中,很小概率会遇到日期格式错乱,如:将Excel中的日期导入到SAS后就变成一个字符型的数字 在SAS中换算一下就可以更正

  10. 2019杭电多校三 C. Yukikaze and Demons (点分治)

    大意: 给定树, 每个点有一个十进制数位, 求有多少条路径组成的十进制数被$k$整除. 点分治, 可以参考CF715C, 转化为求$10^a x+b\equiv 0(mod\space k)$的$x$ ...