HttpClient的超时设置

HttpClient的超时设置

最新线上出现任务积压,通过jstack导出线程堆栈信息,发现所有的线程都卡在HTTP请求执行阶段。

"eis-processor-pool-28" #6480 prio=5 os_prio=0 tid=0x00007f0af6e42800 nid=0x1328f runnable [0x00007f1229fdd000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.read(SocketInputStream.java:150)
	at java.net.SocketInputStream.read(SocketInputStream.java:121)
	at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
	at sun.security.ssl.InputRecord.read(InputRecord.java:503)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
	- locked <0x00000004e27db610> (a java.lang.Object)
	at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:911)
	at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
	- locked <0x00000004e27dd288> (a sun.security.ssl.AppInputStream)
	at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
	at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
	at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282)
	at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
	at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
	at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
	at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
	at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165)
	at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
	at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)

出现这种问题的原因是由于HttpClient没有设置超时,导致客户端一直等待服务器响应,如果服务器没有响应则会一直等待下去。如果服务器没有响应的问题经常发生,那么最终会耗尽线程池资源,导致任务积压。

要解决这个问题需要对HttpClient设置超时,由于每个HttpClient版本设置超时的方式不同,所以要根据自己使用的版本信息区别设置。我们使用的是 4.5.3 版本。该版本有三个超时控制配置:

  • connectionRequestTimeout : 从连接池获取连接的超时时间,单位毫秒。
  • connectTimeout:创建到服务器的连接超时时间,单位毫秒。
  • socketTimeout: socket读取数据超时时间,也是从服务器获取响应数据的超时时间,单位毫秒。

具体设置方法如下:

RequestConfig requestConfig = RequestConfig.custom()
	.setConnectionRequestTimeout(5 * 1000) // 从连接池中获取连接的超时时间
	.setConnectTimeout(5 * 1000) //与服务器连接超时时间:httpclient会创建一个异步线程用以创建socket连接,此处设置该socket的连接超时时间
	.setSocketTimeout(30 * 1000) //socket读数据超时时间:从服务器获取响应数据的超时时间
	.build();
	
CloseableHttpClient httpClient = HttpClientBuilder.create()
	.setMaxConnTotal(10) //连接池中最大连接数
	/**
	 * 分配给同一个route(路由)最大的并发连接数。
	 * route:运行环境机器 到 目标机器的一条线路。
	 * 举例来说,我们使用HttpClient的实现来分别请求 www.baidu.com 的资源和 www.bing.com 的资源那么他就会产生两个route。
	 */
	.setMaxConnPerRoute(2)
	.setDefaultRequestConfig(requestConfig)
	.build();

return httpClient;
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值