为什么要设置HTTP timeout?
先看一个不设置timeout造成的线上事故。
一次线上事故
有一次生产上的一个服务出了点故障,一个原本每5分钟执行一次的定时任务突然不执行了。第一反应是任务执行报错,查看日志,却没有找到任何异常报错信息。
但通过日志可以确定的是,该任务线程还在执行中。按照这个定时任务执行的业务逻辑来说,这是不正常的,除了一个HTTP请求外,其它都是不耗时的操作。那么问题只可能是出在HTTP请求之上了。
通过jstack查看线程的堆栈信息,确定了就是HTTP请求的问题了。

从上面的堆栈信息,可以看到该定时任务线程处于“RUNNABLE”状态,在JVM中"RUNNABLE"表示线程运行在JVM中,但在等待操作系统的其他资源。从堆栈信息中看到,该线程正在进行Socket的读取操作。
从发现任务执行,到定位到这里,已经过去十几分钟了,Socket一直在读取等待中,说明没有设置超时时间,或者说超时时间没有生效。
回头看程序代码,发现这个服务的HTTP工具类没有设置HTTP timeout。随后,赶紧设置timeout。
总结
通常健壮的程序都是要设置超时时间的,上面的程序没有设置超时时间,可以说是一段有缺陷的代码。可是这样一段有缺陷的代码,为什么能在生产环境跑了很久,最后才暴露出问题呢?
我想主要是因为,即使你不设置超时时间,在正常情况下,一个HTTP请求总是会返回结果,即使可能会耗时较长。对于一个负载不高的服务来说,潜在的问题没有暴露出来。
那么什么情况下,没有设置超时时间会造成严重的影响呢?
- 与用户操作相关的接口,如果不设置超时时间,将会出现长时间的无响应,严重影响用户体验。
- 负载很高的系统,因为大量调用耗时长的接口,导致性能急剧下降,从而影响其他正常的业务。
- 某些情况下,HTTP请求可能永远都得不到响应,那么这部分系统资源就一直被占用,直到系统奔溃。
前面两种情况比较好理解,问题是什么情况下,HTTP请求会永远得不到响应呢?
了解计算机网络应该都知道TCP建立连接时的三次握手和断开连接时的四次挥手。
TCP在断开连接时,如果出现异常情况,导致TCP连接的一端异常奔溃,比如电源掉电、系统奔溃、网络故障等。
在这种情况下,TCP的断开操作不会通知对端程序,从而导致对端程序一直处于等待状态,Socket不能及时释放。这种一端开着,一端已经关闭的状态,被称为半开连接。
回顾上面的生产故障,它刚好就是处于“半开连接”的状态,导致任务线程一直在等待响应结果。为了避免这种情况的发生,超时时间是必须要设置的。
为什么要设置HTTP timeout?的更多相关文章
- 【BASIS系列】SAP 设置系统timeout时间
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[BASIS系列]SAP 设置系统timeout ...
- 项目server中设置session timeout遇到的问题
RT:在项目server中的web.xml设置session timeout=10,当10分钟后,继续右键执行jsp文件,运行失败,如下图所示: 但是单独启动tomcat server后,在浏览器中输 ...
- Cloudservice程序设置Idle timeout
部署的云服务程序,默认的idle timeout是4分钟,意味着如果你通过一个workerrole发布了wcf服务,客户端第一次调用服务方法后,再过4分钟尝试去重新调用服务,会报错,具体测试如下: 1 ...
- 设置请求timeout超时
import requests r = requests.get("http://www.cnblogs.com/yoyoketang/", timeout=1) # 设置超时 p ...
- Apache HttpAsyncClient 如何设置per request timeout
最近做一个项目时用到HttpAsyncClient:因项目所需,要求能对一个具体的request 设置连接和读写超时:但发现在HttpAsyncClient中,只有在创建一个HttpAsyncClie ...
- urllib的实现---timeout,获取http响应码,重定向,proxy的设置
1.Timeout设置超时 只能修改Socket设置全局Timeout #! /usr/bin/env python3 import socket import urllib.request # ti ...
- python socket timeout设置
需要在调用socket的connect方法之前设置settimeout(time)方法,另外在设置之后要将再次调用settimeout(None)来设置socket进入阻塞模式. 如下代码示例: so ...
- nginx长连接设置
http { keepalive_timeout 20; --长连接timeout keepalive_requests 8192; --每个连接最大请求数} events { worker_conn ...
- asp.net web.config 设置Session过期时间
在Asp.net中,可以有四处设置Session的过期时间:(原文作者:望月狼地址:http://www.cnblogs.com/wangyuelang0526/) 一.全局网站(即服务器)级 IIS ...
随机推荐
- golang 学习 (八)协程
一: 进程.线程 和 协程 之间概念的区别: 对于 进程.线程,都是有内核进行调度,有 CPU 时间片的概念,进行 抢占式调度(有多种调度算法) (补充: 抢占式调度与非抢占(轮询 ...
- linux系统界面转换
普通使用的切换: 命令行->图形 startx 或者 ctrl+alt+F7切换到图形界面,虚拟机里面使用Alt+F7返回到图形界面 图形->命令行 Ctrl+Alt+F1--F6 如果想 ...
- mysql查看和设置最大连接数
.查看最大连接数 SHOW VARIABLES LIKE '%max_connections%'; .修改最大连接数 ;
- Jenkins控制台乱码修改
原文地址:https://www.jianshu.com/p/8b9df45df401 方案一. 设置jenkins所在服务器环境变量,右键我的电脑→属性→高级系统设置→环境变量,添加JAVA_TOO ...
- 虚拟机中使用Samba实现文件共享
首先我们给虚拟机安装samba服务(如果搭的是别的仓库记得开仓库) 输入命令:yum install samba samba服务的配置文件在,我们来看一下/etc/samba/smb.conf 输入命 ...
- 软件素材---linux C语言:向文件末尾进行追加数据
void AppendDataToFile(char* filePath, char* msg) { // 以附加方式打开可读/写的文件, 如果没有此文件则会进行创建,然后以附加方式打开可读/写的文件 ...
- Jenkins+maven+gitlab自动化部署之构建Java应用(五)
前面几篇文章介绍jenkins部署以及配置,接下来我们,就介绍下如何使用jenkins发布应用. 1)新建项目 jenkins首页,点击左上新建任务,出现下图,填写对应信息,然后点击确定: 2)项目参 ...
- Python32之类和对象2(self参数及魔法方法)
一.类方法中的self参数含义 在Python中类的方法都要有self参数,其实质为对类的实例化对象的绑定从而使得在类的实例化对象调用方法时能够确认出是对哪个对象进行操作. 带self的的参数是人家实 ...
- WSL部署记录
1. 管理员打开PowerShell,开启WSL功能: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Sub ...
- vue基于 element ui 的按钮点击节流
vue的按钮点击节流 场景: 1.在实际使用中,当我们填写表单,点击按钮提交的时候,当接口没返回之前,迅速的点击几次,就会造成多次提交. 2.获取验证码,不频繁的获取. 3.弹幕不能频繁的发 基于这几 ...