Apache HttpClient 4.5: 连接重置

6
我正在使用httpClient 4.5版本连接我们的外部供应商网站。我们不需要任何连接池或持久连接,所以我正在使用BasicHttpClientConnectionManager创建HttpClient。
这对于最小数量的请求可以正常工作,但如果我测试1TPS 1小时,到测试结束时,我们开始看到间歇性的连接重置。(猜测请求计数 > 100)
在处理对{s}->https://apiURL:443的请求时捕获了I/O异常(java.net.SocketException):连接重置。
请查找下面的代码片段以进行连接。
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提供。

如果是这样的话,我不确定为什么我仍然遇到这个问题。请问有人能帮忙吗?

谢谢!


你有没有考虑到对端重置连接的可能性? - ok2c
感谢您的回复,Oleg。根据我们与网络团队运行的跟踪,我们发现源服务器在目标主机请求 ACK 时发送了大量的重置 (RST)。因此,我正在尝试确定是否是我们使用的 HttpClient 的问题。 - user1347244
目前为止,我们所做的是将重试次数增加到3次(使用DefaultHttpRequestRetryHandler),因为我们注意到一些请求在遇到连接重置错误后经过重试后可以成功处理。但是,这似乎并不是我们面临的问题的适当解决方案。 - user1347244
1
我怀疑服务器无法跟上负载并且会断开无法处理的连接。对于安全和幂等方法,重试策略应该是完全足够的解决方案。 - ok2c
谢谢 Oleg,我想你是对的,我们也得出了类似的结论。如果在与客户端连接方面还有其他尝试的方法,请告诉我。 - user1347244
1个回答

4

你好,Oleg

之前我一直在使用httpclient版本4.5.3,但仍然遇到了如上所述的连接重置错误。

后来发现修复重置问题的方法已经提交到了版本4.5.1(https://issues.apache.org/jira/browse/HTTPCLIENT-1655)。因此,我尝试更新该特定版本,运行测试,不再看到连接重置错误。

我本来以为这个修复程序也应该在从4.5.1开始的更高版本中可用。但是,我猜它在更高版本中被忽略了,确实已经验证对于4.5.3版本仍然存在该问题。

因此,结论是使用httpclient 4.5.1 jar可以解决连接重置错误。

谢谢!


我觉得有点难以置信,但是没办法。 - ok2c
是的,我也没有考虑到这种可能性。如果我没有尝试使用不同版本运行多轮测试,我也不会那么确定。这只是一个试验,但我很高兴解决了它。希望您也会将修复程序添加到更高版本中。 - user1347244
问题在于,由于HTTPCLIENT-1655存在于所有4.5.x版本自4.5.1以来,我不知道该修复什么。我已经进行了双重检查。 - ok2c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接