You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RestTemplate发起POST请求遇Connection pool shut down异常求助

RestTemplate 出现 Connection pool shut down 异常的解决方案

问题描述

使用RestTemplate发起POST请求时抛出以下异常:

Caused by: java.lang.IllegalStateException: Connection pool shut down
    at org.apache.http.util.Asserts.check(Asserts.java:34) ~[httpcore-4.4.15.jar:4.4.15]
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:269) ~[httpclient-4.5.13.jar:4.5.13]
    ...

当前使用httpclient:4.5.13,通过RestTemplateBuilder默认构建RestTemplate,未手动管理连接池。重启服务后异常暂时消失,但处理一定量请求后会再次出现。

原因分析

  • 默认连接池配置参数不合理,无法适配业务请求量,导致连接资源耗尽后触发连接池关闭逻辑;
  • 存在连接泄漏,未正确释放请求连接,导致连接池资源被占满;
  • 重复创建RestTemplate实例,生成多个独立连接池,最终资源耗尽;
  • Spring上下文生命周期异常,导致连接池被提前销毁。

解决方案

1. 手动配置HttpClient连接池

通过自定义连接池参数,精准控制连接生命周期,避免默认配置的隐患:

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        // 初始化连接池管理器
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        // 设置最大总连接数,根据业务调整
        connectionManager.setMaxTotal(200);
        // 设置单个路由的最大连接数
        connectionManager.setDefaultMaxPerRoute(50);
        // 配置请求超时参数
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)       // 建立连接超时时间(ms)
                .setSocketTimeout(10000)       // 读取响应超时时间(ms)
                .setConnectionRequestTimeout(5000) // 从连接池获取连接的超时时间(ms)
                .build();

        // 构建HttpClient,添加连接池清理策略
        CloseableHttpClient httpClient = HttpClientBuilder.create()
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .evictIdleConnections(30, TimeUnit.SECONDS) // 定期清理30秒空闲的连接
                .evictExpiredConnections()                  // 清理过期连接
                .build();

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(requestFactory);
    }
}

之后在业务类中直接注入该单例RestTemplate即可:

@Autowired
public ClientImpl(RestTemplate restTemplate) {
    this.restTemplate = restTemplate;
}

2. 排查并修复连接泄漏

  • 确保所有RestTemplate请求都在异常处理范围内,避免因未捕获异常导致连接无法释放:
    try {
        restTemplate.postForObject(url, request, responseType);
    } catch (RestClientException e) {
        // 异常处理逻辑
        log.error("请求失败", e);
    }
    
  • 开启HttpClient调试日志,跟踪连接状态:将org.apache.http的日志级别设为DEBUG,查看连接的创建、释放情况,定位未释放的连接来源。

3. 避免重复创建RestTemplate实例

禁止通过RestTemplateBuilder.build()每次创建新实例,确保RestTemplate在Spring容器中是单例Bean,避免生成多个独立连接池导致资源耗尽。

4. 排查Spring上下文生命周期问题

  • 检查自定义Bean的销毁逻辑,确认没有误调用PoolingHttpClientConnectionManager.shutdown()方法;
  • 确保连接池管理器由Spring容器管理,其生命周期与容器一致,避免手动提前销毁。

内容的提问来源于stack exchange,提问作者user09

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:15:02