設置`SocketTimeout=60000`(60秒),實際請求在約21秒超時;只有設置<21秒時生效。
HttpClient 4.x 默認使用連接管理器的連接請求超時(`ConnectionRequestTimeout`)默認值較小,且DNS解析、建立連接、TLS握手等階段受系統級超時限制(Linux默認TCP連接超時約20秒)。
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(60000) // 建立連接超時(TCP三次握手)
.setSocketTimeout(60000) // 數據傳輸超時(讀取數據間隔)
.setConnectionRequestTimeout(60000) // 從連接池獲取連接超時
.setRedirectsEnabled(true) // 允許重定向
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(50);
// 關鍵:設置連接管理器級別的驗證超時
cm.setValidateAfterInactivity(10000); // 空閒連接驗證間隔
CloseableHttpClient client = HttpClients.custom()
.setDefaultRequestConfig(config)
.setConnectionManager(cm)
.evictIdleConnections(30, TimeUnit.SECONDS) // 定期清理空閒連接
.build();
若仍受限於內核TCP超時(`/proc/sys/net/ipv4/tcp_syn_retries` 默認6次 ≈ 127秒,但某些環境默認更小),可通過以下方式:
原代碼中`setStaleConnectionCheckEnabled(true)`已棄用,且未設置`ConnectionRequestTimeout`,導致從池獲取連接時使用默認值(可能極小)。