【发布时间】:2017-08-04 20:13:57
【问题描述】:
我正在使用 httpClient 4.5 版连接我们的外部供应商网站。我们不需要任何连接池或持久连接,所以我使用 BasicHttpClientConnectionManager 来创建 HttpClient。
这适用于最少数量的请求,但如果我以 1TPS 测试 1 小时,在测试结束时,我们开始看到间歇性连接重置。 (猜测请求数 > 100)
处理对 {s}->https://apiURL:443 的请求时捕获的 I/O 异常 (java.net.SocketException):连接重置
请在下面找到用于建立连接的代码sn-p。
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), new X509TrustManager[] { new DefaultTrustManager() }, new SecureRandom());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" }, null,SSLConnectionSocketFactory.getDefaultHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslsf).register("http", new PlainConnectionSocketFactory()).build();
HttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager(socketFactoryRegistry);
HttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(1, false);
RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(Integer.parseInt(30000)).setConnectTimeout(Integer.parseInt(30000)).setConnectionRequestTimeout(30000).setCookieSpec(CookieSpecs.STANDARD).build();
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).setDefaultRequestConfig(defaultRequestConfig).setRetryHandler(retryHandler).evictExpiredConnections().build();
HttpPost httpPost = new HttpPost(<endpoint>);
httpPost.setEntity(new UrlEncodedFormEntity(requestData));
httpResponse = httpClient.execute(httpPost);
我看到针对报告的类似问题的修复已在 4.5 版中可用。 (参考:https://issues.apache.org/jira/browse/HTTPCLIENT-1655)由Oleg提供
如果是这样,不知道为什么我仍然面临这个问题。有人可以帮忙吗?
谢谢!
【问题讨论】:
-
是否考虑过对端端点重置连接的可能性?
-
感谢Oleg 的回复。从我们在这里与网络团队运行的跟踪中可以看出,当目标主机向我们请求 ACK 时,源,即我们的服务器一直在发送大量重置 (RST)。所以,这就是我试图弄清楚这是否是我们使用的 HttpClient 的问题的原因。
-
此时,我们所做的就是将重试次数增加到 3(使用 DefaultHttpRequestRetryHandler),因为我们注意到一些被连接重置错误命中的请求在重试。但是,对于我们面临的问题,这似乎不是一个合适的解决方案。
-
我怀疑服务器无法跟上负载并丢弃无法提供服务的连接。对于安全和幂等的方法,重试策略应该是一个完美的解决方案。
-
谢谢Oleg,我猜你是对的,我们也得出了类似的结论。如果我可以从与客户端的连接的角度尝试其他任何事情,请告诉我。
标签: java https httpclient apache-httpclient-4.x