resttemplate 默认仅允许每个目标主机最多 2 个并发连接,导致第 3 个请求被阻塞;根本原因在于底层 httpclient 使用了默认连接池配置,需显式配置 poolinghttpclientconnectionmanager 并调大 maxtotal 和 defaultmaxperroute 参数。
resttemplate 默认仅允许每个目标主机最多 2 个并发连接,导致第 3 个请求被阻塞;根本原因在于底层 httpclient 使用了默认连接池配置,需显式配置 poolinghttpclientconnectionmanager 并调大 maxtotal 和 defaultmaxperroute 参数。
在 Spring 应用中,RestTemplate 本身不管理连接,而是依赖其底层 HTTP 客户端(如 Apache HttpClient)的连接池机制。你当前的配置使用了 HttpClients.custom().build(),该方式会创建一个默认的 PoolingHttpClientConnectionManager 实例——而该管理器的默认最大总连接数为 2,且每个路由(即每个目标 host:port)的默认最大连接数也为 2。这就是为何第三个请求会被挂起等待:连接池已满,新请求必须等待已有连接释放。
要彻底解决此瓶颈,需显式构造并配置 PoolingHttpClientConnectionManager,再将其注入 CloseableHttpClient。以下是推荐的生产级配置示例:
@Bean
public RestTemplate restTemplate() throws Exception {
// 1. 配置信任所有证书的 SSL(仅限测试环境!生产环境请使用可信证书)
TrustStrategy acceptingTrustStrategy = (chain, authType) -> true;
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
// 2. 显式创建并配置连接池管理器
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(100); // 全局最大连接数
connectionManager.setDefaultMaxPerRoute(20); // 每个路由(如 https://api.example.com)最大 20 连接
// (可选)为特定域名设置更高限额(例如对接高并发网关)
HttpHost apiHost = new HttpHost("api.example.com", 443, "https");
connectionManager.setMaxPerRoute(new HttpRoute(apiHost), 50);
// 3. 构建 HttpClient 并注入连接管理器与 SSL 工厂
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.setSSLSocketFactory(socketFactory)
.setConnectionTimeToLive(30, TimeUnit.SECONDS) // 连接保活时间
.evictIdleConnections(60, TimeUnit.SECONDS) // 定期清理空闲连接
.build();
// 4. 绑定到 RestTemplate
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
factory.setConnectTimeout(5000); // 连接超时:5s
factory.setReadTimeout(10000); // 响应超时:10s
return new RestTemplate(factory);
}
✅ 关键参数说明:
- setMaxTotal(100):整个连接池最多维持 100 个活跃连接(含所有目标主机);
- setDefaultMaxPerRoute(20):对任意未单独配置的 host,默认最多建立 20 个并发连接;
- setMaxPerRoute(..., 50):可针对关键服务精细化控制,避免单点耗尽全局连接资源;
- evictIdleConnections 与 setConnectionTimeToLive:防止连接泄漏和 stale 连接堆积,提升稳定性。
⚠️ 重要注意事项:
- 切勿在生产环境使用 acceptingTrustStrategy —— 它会禁用 HTTPS 证书校验,带来严重安全风险。生产环境应加载真实 CA 证书或使用 KeyStore 管理客户端证书;
- 连接数并非越大越好:过高的 maxTotal 可能压垮目标服务或本地文件描述符(Linux 默认限制约 1024),建议结合压测与监控(如 connectionManager.getTotalStats())动态调优;
- 若使用 Spring Boot 2.0+,更推荐迁移到 WebClient(基于 Netty,非阻塞、天然高并发),RestTemplate 已处于维护模式。
通过上述配置,你的 RestTemplate 将具备可伸缩的并发能力,彻底消除“第三个请求被阻塞”的现象,同时兼顾安全性与运行时健壮性。










