Apache HttpAsyncClient调用出现Connection reset by peer错误求助
解决Apache HttpAsyncClient的Connection reset by peer问题
我来帮你分析下这个问题,Connection reset by peer本质是TCP连接被对方服务器主动断开了,结合你的代码和依赖配置,咱们从几个方向来排查解决:
1. 先修复依赖版本兼容性问题
你的依赖版本存在不匹配的情况:httpasyncclient 4.1.3和httpclient 4.5.5、httpcore 4.4的组合可能会导致底层IO处理的兼容性问题。Apache HttpComponents组件的版本需要配套使用,建议统一为兼容的版本组合:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpasyncclient</artifactId> <version>4.1.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> <!-- 与httpasyncclient 4.1.3配套 --> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.6</version> <!-- 与httpasyncclient 4.1.3配套 --> </dependency>
2. 修复代码中的资源泄漏问题
你的回调方法里没有正确关闭HTTP响应的资源,这会导致连接池中的连接无法被正常回收,服务器可能因为连接占用超时而主动断开连接。请务必在处理完响应后释放资源:
修改completed方法的代码,用try-with-resources自动关闭流,同时释放响应实体:
@Override public void completed(final HttpResponse response) { latch.countDown(); // 使用try-with-resources自动关闭流 try (BufferedReader in = new BufferedReader( new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8))) { String data; while ((data = in.readLine()) != null) { // process the data } // 确保实体资源被完全释放 EntityUtils.consume(response.getEntity()); } catch (IOException e) { e.printStackTrace(); } }
3. 优化HttpAsyncClient的配置
默认的客户端配置可能没有合理设置超时和并发参数,导致连接在服务器端超时被重置。建议手动配置连接超时、Socket超时,以及调整连接池和IO线程数:
// 配置请求超时 RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(5000) // 连接超时5秒 .setSocketTimeout(10000) // Socket超时10秒 .setConnectionRequestTimeout(5000) // 从连接池获取连接的超时 .build(); // 配置连接管理器 PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager( IOReactorConfig.custom() .setIoThreadCount(Runtime.getRuntime().availableProcessors()) // 设置IO线程数 .build()); connManager.setMaxTotal(20); // 最大总连接数 connManager.setDefaultMaxPerRoute(10); // 每个路由的最大连接数 // 构建客户端 CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() .setConnectionManager(connManager) .setDefaultRequestConfig(requestConfig) .build();
4. 其他排查方向
- 服务器限流/并发限制:如果目标服务器对并发请求数有严格限制,你的并行请求可能触发了限流机制,导致连接被重置。可以尝试降低并发数(比如先改成2个请求测试),或者添加请求间隔。
- SSL证书/握手问题:因为你请求的是HTTPS接口,可能客户端不认可服务器的SSL证书,或者加密套件不兼容导致SSL握手失败,进而连接被重置。测试环境可以临时配置信任所有证书(生产环境不建议),生产环境请导入正确的CA证书:
// 测试用:信任所有SSL证书(仅用于排查,生产禁用) SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial((chain, authType) -> true) .build(); CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() .setSSLContext(sslContext) .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) // 加上之前的配置 .build();
按照上面的步骤逐一排查,应该能解决Connection reset by peer的问题。
内容的提问来源于stack exchange,提问作者applicationMVP
相关产品推荐
相关产品推荐

