最近在做一个定时任务,每一个小时使用HttpClient去访问一个外部服务器拉去一组数据,使用一个大小为10的线程池启动拉取线程,昨天外部服务器挂了一次,然后发现我自己的服务器上的线程池也挂了,提交的新task全部无法执行。奇怪的是外部服务器昨天挂了,今天就恢复了,我自己的服务器今天应该也自动恢复才对啊,我重启了自己的服务器的进程就OK了,但为什么线程池会挂呢,即使外部服务恢复了,本地线程池必须要重启来才能恢复,这是为何?
本地写了一个小测试程序,自己搭建了一个简单的http server,在server的服务方法中启动死循环(或者直接打断点不退出),就发现client端的请求线程一直卡住不会释放,如果这个是线程池中的线程,就会一直占用线程池资源,导致线程池不能响应后续的的任务。
解决办法,设置socket超时时间:
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
builder.build());
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000)
.setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();
CloseableHttpClient client = HttpClientBuilder.create().setMaxConnTotal(3)
.setMaxConnPerRoute(10000).setSSLSocketFactory(sslsf).build();
// URI uri = UriBuilder.fromPath("http://localhost:8080/")
URI uri = UriBuilder.fromPath("https://localhost:8443/")
.segment("hello-world")
.segment("get")
.build();
HttpGet get = new HttpGet(uri);
get.setConfig(requestConfig);
System.out.println("http start")