HttpClient大并发下Timeout waiting for connection from pool优化方案

Java开发总结 专栏收录该内容
17 篇文章 0 订阅

(本文的优化方案是由同事给出,我就对此做一下整理,记录分享给大家)


当前用的httpclient  jar 包是 httpclient-4.3.6,相对应之前的版本是有一些不同的,用起来也会出现一些问题,但是可以通过配置参数解决我遇到的问题

HttpClient一些正常所需的参数:

//设置连接超时时间

private static int socketTimeout = 2000;
private static int connectTimeout = 2000;
private static int connectionRequestTimeout = 10000;

在做性能测试时,tps=50时,绝大部分的请求都是正常的,只有少数请求抛出了如下异常:

2015-12-23 11:50:45.716 INFO  [[ACTIVE] ExecuteThread: '21' for queue: 'weblogic.kernel.Default (self-tuning)'] AssetCrowdFundQueryServiceImpl line35 - AssetCrowdFundQueryServiceImpl queryCrowdFunding is SUCCESS, Exception{}
java.io.IOException: org.apache.http.conn.ConnectionPoolTimeoutException: <span style="color:#ff0000;">Timeout waiting for connection from pool</span>
         at com.pingan.toa.asset.common.utils.http.HttpClientUtil.post(HttpClientUtil.java:180) ~[asset-common-1.0.0-SNAPSHOT.jar:na]
         at com.pingan.toa.asset.common.utils.http.HttpClientUtil.post(HttpClientUtil.java:158) ~[asset-common-1.0.0-SNAPSHOT.jar:na]
         at com.pingan.toa.asset.service.crowdfunding.impl.AssetCrowdFundQueryServiceImpl.queryCrowdFunding(AssetCrowdFundQueryServiceImpl.java:32) ~[asset-service-1.0.0-SNAPSHOT.jar:na]
         at com.pingan.toa.asset.facade.crowdfunding.impl.CrowdFundingAssetFacadeImpl.getCrowdFundInfo(CrowdFundingAssetFacadeImpl.java:173) ~[asset-facade-1.0.0-SNAPSHOT.jar:na]
         at sun.reflect.GeneratedMethodAccessor145.invoke(Unknown Source) ~[na:na]
         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_37]
         at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_37]
         at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:188) ~[cxf-api-2.7.17.jar:2.7.17]
         at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:104) ~[cxf-api-2.7.17.jar:2.7.17]
         at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:204) ~[cxf-rt-frontend-jaxrs-2.7.17.jar:2.7.17]
         at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:101) ~[cxf-rt-frontend-jaxrs-2.7.17.jar:2.7.17]
         at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58) ~[cxf-api-2.7.17.jar:2.7.17]
         at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:94) ~[cxf-api-2.7.17.jar:2.7.17]
         at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272) ~[cxf-api-2.7.17.jar:2.7.17]
         at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[cxf-api-2.7.17.jar:2.7.17]
         at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:249) ~[cxf-rt-transports-http-2.7.17.jar:2.7.17]
         at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248) ~[cxf-rt-transports-http-2.7.17.jar:2.7.17]
         at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222) ~[cxf-rt-transports-http-2.7.17.jar:2.7.17]
         at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:154) ~[cxf-rt-transports-http-2.7.17.jar:2.7.17]
         at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171) ~[cxf-rt-transports-http-2.7.17.jar:2.7.17]
         at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:290) ~[cxf-rt-transports-http-2.7.17.jar:2.7.17]
         at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:210) ~[cxf-rt-transports-http-2.7.17.jar:2.7.17]
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) ~[javax.servlet_1.0.0.0_2-5.jar:2.5]
         at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:265) ~[cxf-rt-transports-http-2.7.17.jar:2.7.17]
         at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227) ~[weblogic.jar:10.3.6.0]
         at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125) ~[weblogic.jar:10.3.6.0]
         at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301) ~[weblogic.jar:10.3.6.0]
         at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:27) ~[weblogic.jar:10.3.6.0]
         at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:61) ~[BUG20181997_1036011.jar:10.3.6.0]
         at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:89) ~[spring-web-3.2.14.RELEASE.jar:3.2.14.RELEASE]
         at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106) ~[spring-web-3.2.14.RELEASE.jar:3.2.14.RELEASE]
         at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:61) ~[BUG20181997_1036011.jar:10.3.6.0]
         at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3748) ~[BUG20181997_1036011.jar:10.3.6.0]
         at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3714) ~[BUG20181997_1036011.jar:10.3.6.0]
         at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) ~[com.bea.core.weblogic.security.identity_1.2.0.0.jar:1.2.0.0]
         at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120) [com.bea.core.weblogic.security.wls_1.0.0.0_6-2-0-0.jar:6.2.0.0]
         at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2283) [BUG20181997_1036011.jar:10.3.6.0]
         at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2182) [BUG20181997_1036011.jar:10.3.6.0]
         at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1491) [BUG20181997_1036011.jar:10.3.6.0]
         at weblogic.work.ExecuteThread.execute(ExecuteThread.java:263) [BUG20181997_1036011.jar:1.11.0.0]
         at weblogic.work.ExecuteThread.run(ExecuteThread.java:221) [BUG20181997_1036011.jar:1.11.0.0]
Caused by: org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
         at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:254) ~[httpclient-4.3.6.jar:4.3.6]
         at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:231) ~[httpclient-4.3.6.jar:4.3.6]
         at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:173) ~[httpclient-4.3.6.jar:4.3.6]
         at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) ~[httpclient-4.3.6.jar:4.3.6]
         at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86) ~[httpclient-4.3.6.jar:4.3.6]
         at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) ~[httpclient-4.3.6.jar:4.3.6]
         at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) ~[httpclient-4.3.6.jar:4.3.6]
         at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) ~[httpclient-4.3.6.jar:4.3.6]
         at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106) ~[httpclient-4.3.6.jar:4.3.6]
         at com.pingan.toa.asset.common.utils.http.HttpClientUtil.post(HttpClientUtil.java:174) ~[asset-common-1.0.0-SNAPSHOT.jar:na]
         ... 40 common frames omitted

HttpClient在并发量高的时候,可能会出现连接池不够用的情况,可以通过配置总体最大连接池( maxConnTotal)和单个路由连接最大数( maxConnPerRoute),默认是(20,2)

maxConnTotal  maxConnPerRoute 的区别?

maxConnTotal 是整个连接池的大小,根据自己的业务需求进行设置

maxConnPerRoute 是单个路由连接的最大数,可以根据自己的业务需求进行设置

比如maxConnTotal =200,maxConnPerRoute =100,那么,如果只有一个路由的话,那么最大连接数也就是100了;如果有两个路由的话,那么它们分别最大的连接数是

100,总数不能超过200

   private static CloseableHttpClient httpClient;
   private static int socketTimeout = 2000;
   private static int connectTimeout = 2000;
   private static int connectionRequestTimeout = 10000;
   private static int maxConnTotal = 200;   //最大不要超过1000
   private static int maxConnPerRoute = 100;//实际的单个连接池大小,如tps定为50,那就配置50
   
   public static void init() {
      RequestConfig config = RequestConfig.custom()
            .setSocketTimeout(socketTimeout)
            .setConnectTimeout(connectTimeout)
            .setConnectionRequestTimeout(connectionRequestTimeout).build();
      httpClient = HttpClients.custom().setDefaultRequestConfig(config)
            .setMaxConnTotal(maxConnTotal)
            .setMaxConnPerRoute(maxConnPerRoute).build();
   }
         
   public static int getMaxConnTotal() {
      return maxConnTotal;
   }

   public static void setMaxConnTotal(int maxConnTotal) {
      HttpClientUtil.maxConnTotal = maxConnTotal;
   }

   public static int getMaxConnPerRoute() {
      return maxConnPerRoute;
   }

   public static void setMaxConnPerRoute(int maxConnPerRoute) {
      HttpClientUtil.maxConnPerRoute = maxConnPerRoute;
   }

当然,这些参数都是可以在配置文件里设置的。


  • 4
    点赞
  • 1
    评论
  • 6
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值