zoukankan      html  css  js  c++  java
  • 一次HttpClient连接泄露排查

    一次HttpClient连接泄露排查

    在开发环境中,调试新功能时发现由于异常处理不严谨导致线程一直挂起的问题。

    故障

    在集成测试用,发现只要多次调用新开发的业务,就会出现前端卡死,后端响应线程一直挂起的情况,但没有任何报错

    查错

    每一次重现的时候最后一条log都是定位到有些历史的HttpClient的工具类上,接口封装上游是直接一个大块try-catch并且没有做任何的异常处理,调用的下游才是直接对Apache HttpClient的封装,眨眼看上去并没有什么问题。
    因为业务时异步并发调用接口,我在业务调用上改成timeout处理,断点发现有任务处于未完成状态,远程调用一直没有回调。然后我重新打开工具类,找到封装HttpClient调用的逻辑,搜索关于timeout的设置,如下:

    	RequestConfig
                    .custom()
    		.setSocketTimeout(socketTimeout)
    		.setConnectTimeout(connectTimeout)
    		.build();
    

    然后看了一下文档,发现还有一个timeout的参数ConnectionRequestTimeout,然后我改动一下代码:

    	RequestConfig
                     .custom()
    		 .setSocketTimeout(socketTimeout)
    	         .setConnectTimeout(connectTimeout)
    		 .setConnectionRequestTimeout(requestTimeOut)
    		 .build();
    

    再次编译运行,问题依旧,但有了新发现,有新的异常捕获日志:

    org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection
    

    然后定位到调用下游逻辑块:

    	HttpResponse resp = client.execute(httpPost);	//这里!
    	if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
    		HttpEntity httpEntity = resp.getEntity();
    		respContent = EntityUtils.toString(httpEntity, "UTF-8");
    	}
    

    这段代码中抛出了异常,给上游的调用捕获了,但是上下文中httpPost并没有做连接释放的处理,所以连接池中的连接越来越少。

    解决

    在逻辑中加上try-finally,显式调用释放请求连接。

    	try {
    		HttpResponse resp = client.execute(httpPost);
    		if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
    			HttpEntity httpEntity = resp.getEntity();
    			respContent = EntityUtils.toString(httpEntity, "UTF-8");
    			EntityUtils.consume(httpEntity);
    		}
    	} finally {
    		httpPost.releaseConnection();
    	}
    
  • 相关阅读:
    ES6学习笔记(11)----Proxy
    ES6学习笔记(10)----Set和Map数据结构
    ES6学习笔记(9)----Symbol
    ES6学习笔记(8)----对象的扩展
    ES6学习笔记(6)----函数的扩展
    ES6学习笔记(5)----数值的扩展
    struts2学习之基础笔记1
    前端面试---常见的web安全及防护原理
    前端面试整理笔记一
    id选择器
  • 原文地址:https://www.cnblogs.com/jason-koo/p/12905362.html
Copyright © 2011-2022 走看看