
RestTemplate 默认仅允许每个目标主机最多 2 个并发 HTTP 连接,导致第 3 个请求被阻塞;根本原因在于底层 HttpClient 使用的 PoolingHttpClientConnectionManager 默认连接池容量过小,需显式配置最大总连接数与每路由连接数。
resttemplate 默认仅允许每个目标主机最多 2 个并发 http 连接,导致第 3 个请求被阻塞;根本原因在于底层 httpclient 使用的 `poolinghttpclientconnectionmanager` 默认连接池容量过小,需显式配置最大总连接数与每路由连接数。
在基于 Spring 的 HTTP 客户端开发中,RestTemplate 是广泛使用的同步 HTTP 工具类。然而,当高并发调用同一服务(如频繁访问 /api/users)时,开发者常遇到“第 3 个请求长时间挂起”的现象——这并非网络或服务端问题,而是 RestTemplate 底层 HttpClient 的连接池配置未适配实际负载所致。
默认情况下,HttpClients.custom().build() 创建的客户端使用 PoolingHttpClientConnectionManager,其全局最大连接数(maxTotal)为 20,但每个路由(route,即 host:port 组合)的默认最大连接数(defaultMaxPerRoute)仅为 2。这意味着:即使你向 https://api.example.com 发起 10 个并行请求,也仅有 2 个能立即复用连接,其余请求将排队等待空闲连接释放,造成显著延迟。
✅ 正确做法是显式构造并配置连接池管理器,再注入到 HttpClient 中。以下是生产就绪的配置示例:
@Bean
public RestTemplate restTemplate() throws Exception {
// 1. 配置 SSL(跳过证书校验仅用于测试,生产环境请使用可信 TrustStore)
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); // 每个 host:port 最多 20 连接(关键!)
// 3. 构建 HttpClient 并注入连接池与 SSL 工厂
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.setSSLSocketFactory(socketFactory)
.setConnectionTimeToLive(30, TimeUnit.SECONDS) // 可选:连接保活时间
.build();
// 4. 绑定到 RestTemplate
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
factory.setConnectTimeout(5000);
factory.setReadTimeout(10000);
return new RestTemplate(factory);
}
⚠️ 重要注意事项:
- setDefaultMaxPerRoute(n) 应 ≥ 预期并发请求数 / 目标主机数量。例如:若同时调用 3 个不同域名,且总并发目标为 60,则建议设为 20(60 ÷ 3)并留有余量;
- setMaxTotal(n) 应 ≥ defaultMaxPerRoute × 主机数,避免连接池全局耗尽;
- 生产环境严禁使用无验证的 acceptingTrustStrategy,务必通过 KeyStore 加载受信 CA 证书;
- 若使用 Spring Boot 2.3+,推荐迁移至 WebClient(响应式、连接池更智能、资源占用更低);
- 可通过 connectionManager.getTotalStats() 和 connectionManager.getStats(host) 动态监控连接使用情况,便于压测调优。
通过上述配置,RestTemplate 即可稳定支撑数十乃至上百级并发请求,彻底消除因连接池瓶颈引发的线程阻塞问题。










