记一次问题处理对http请求超时时间的运用
Posted 流云一号
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次问题处理对http请求超时时间的运用相关的知识,希望对你有一定的参考价值。
时间回到某年某月某日,微信某项目对接群里突然炸锅了。刚上线第三天的项目,系统突然响应超级慢,用户投诉不断。还没等读完所有的消息,现场运维经理也给我打来电话,万分火急,需要开发人员介入排查问题。我赶紧要来远程,连上了现场环境。
首先,通过监控模块查看所有对外提供接口的响应速度,看看是哪个接口响应慢。结果发现,所有接口响应时间全部都很长,感觉系统整个处于一个半瘫痪状态。难道是业务量激增导致系统触及性能瓶颈?带着这个问题,我分析了上午系统正常时的数据库订单数量,并和前两天数据做比对,发现订单并没有太显著的增多,如此排除了业务量激增导致系统不堪重负的可能。
接下来,我开始仔细分析系统日志,发现有一个调用另外一个系统查询社保卡余额的接口有时会超时。问题突然明朗了一些,这个接口超时时间设置的比较长,如果超时的次数比较多,叠加的请求多了,会逐渐耗尽系统资源,导致本系统所有提供的对外接口响应都非常慢。那么接下来需要排查这个查询接口为啥有时超时有时很正常。由于这个系统也是本公司的系统,我很快找到了对应的日志表,筛查响应时间长的请求。观察发现,这些响应时间长的请求都与记录同一个错误,这个错误指向了某银行的系统。我接着联系现场运维经理,询问线下的一些其他业务是否也有一些参保人无法使用,对方说线下也收到了类似的问题反馈。这下基本“破案”了,某地社保卡的发卡行往往有多家银行,这个查询社保卡余额的接口就是根据不同的发卡行去调用具体银行的系统查询,而此时是某个发卡行的系统出问题了。我让现场运维经理联系银行,问啥时候能恢复,银行回复正在排查,尽快恢复。此处,我就不再吐槽了。
原因已经找到,现在摆在我面前的问题是,甲方的业务系统仍然要调用我的系统来实现社保卡消费,而有一部分参保人的发卡行系统又不能用。情况紧急,实现方案只有一个,那就是如何确保其他发卡行的参保人能正常使用我的系统,将投诉量降到最低。整个链路调用的系统较多,而且目前只能先修改本系统,思来想去,可以从http请求的超时时间上下手。
这里,先简单介绍下HTTP请求时connectionRequestTimeout 、connectionTimeout、socketTimeout三个超时时间的含义。
connectionRequestTimout:指从连接池获取连接的timeout。
connetionTimeout:指客户端和服务器建立连接的timeout。就是http请求的三个阶段,一:建立连接;二:数据传送;三,断开连接。建立连接超时后会ConnectionTimeOutException
socketTimeout:指客户端和服务器建立连接后,客户端从服务器读取数据的timeout,超出后会抛出SocketTimeOutException。
本系统间接调用银行的接口主要有两类,一个是查询类,一个是交易类,这类接口都是用的同一个http请求公共方法(这个方法的超时时间写死了,120S)。因为某些原因这些接口有时确实很慢,尤其是交易类接口,所以为了避免单边账超时时间设置的很长。原先的公共方法开头代码如下:
public static JSONObject invokeService(String url, String serviceName, String operationName, String xmlPara ) throws AppException
CloseableHttpClient httpclient = null;
HttpPost httppost = new HttpPost(url);
CloseableHttpResponse response = null;
HttpEntity entity = null;
// 超时时间,这里是写死的
int waitTime = 120000;
最后果断决定,新写一个http请求公共方法,可以传入超时时间,上述查询社保卡余额的接口调用新的方法,并传入较短的超时时间(比如10S),让有问题的发卡行及时抛出超时错误。新方法开头如下:
public static JSONObject invokeServiceWithWaitTime(String url, String serviceName, String operationName, String xmlPara, Integer waitTimePara) throws AppException
CloseableHttpClient httpclient = null;
HttpPost httppost = new HttpPost(url);
CloseableHttpResponse response = null;
HttpEntity entity = null;
int waitTime = 120000; //默认超时时间
if (waitTimePara != null)
waitTime = waitTimePara; //使用传入的超时时间
这样既能减小系统压力,也能保证其他发卡行的参保人正常使用系统。情况紧急,用户投诉仍然不断,甲方客服电话都被打爆了,必须马上升级。我在最短的时间完成了升级,紧接着看监控模块,系统接口响应都恢复了正常。微信群里也传来了好消息,紧张的氛围也降缓和下来了。但作为一个经验丰富的程序员,工作还没有完,我需要排查日志,检查有没有在系统切换的间隙存在实际发生却没有入库的交易数据。所幸,经过仔细排查,没有漏掉的交易数据。经过此事,对http请求的超时时间的使用又有了新的认识。
以上是关于记一次问题处理对http请求超时时间的运用的主要内容,如果未能解决你的问题,请参考以下文章
记一次kubernetes集群异常:kubelet连接apiserver超时