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

Java多线程并发请求时OKHTTP抛出SocketTimeoutException问题求助

问题成因

  • OkHttpClient实例创建过多:OkHttpClient设计为单例复用,每个实例独立持有连接池、调度器、线程池等资源,创建400个独立实例会导致大量冗余资源占用,每个实例的连接管理逻辑互相独立,无法全局复用TCP连接,频繁创建新连接会快速耗尽本机临时端口,导致新建连接超时。
  • 连接池配置错误:此前设置的连接池keepAlive时间仅为100毫秒,远小于两次请求的5秒间隔,完全无法复用连接,每次请求都需要新建TCP连接,进一步加快了端口消耗速度。
  • 资源关闭逻辑存在泄漏风险:当前的响应关闭逻辑没有做异常兜底,如果请求过程中抛出异常未执行到close()方法,会导致TCP连接泄漏,占用端口无法释放。

修复方案

  1. 重构OkHttpClient为全局单例
    不需要为每个代理创建独立OkHttpClient,OkHttp支持请求级别指定代理,全局复用一个实例即可统一管理连接资源,减少不必要的资源开销:
// 全局单例OkHttpClient
OkHttpClient GLOBAL_HTTP_CLIENT = new OkHttpClient.Builder()
    .connectTimeout(7, TimeUnit.SECONDS)
    .writeTimeout(7, TimeUnit.SECONDS)
    .readTimeout(7, TimeUnit.SECONDS)
    .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
    .hostnameVerifier((String hostname, SSLSession session) -> true)
    .addNetworkInterceptor(new LoggingInterceptor())
    .retryOnConnectionFailure(true)
    .connectionPool(new ConnectionPool(400, 5, TimeUnit.MINUTES)) // 匹配最大并发请求数,keepAlive设为5分钟保证连接可复用
    .dispatcher(new Dispatcher(Executors.newCachedThreadPool()))
    .build();
  1. 请求级别指定代理和认证
    每个线程发请求时,为当前Request指定对应代理,认证逻辑可以放在全局proxyAuthenticator中,根据当前路由的代理地址返回对应认证信息即可。

  2. 使用try-with-resources自动关闭响应,避免连接泄漏

while (true) {
    // 为当前请求指定专属代理
    Proxy currentProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ProxyIP, ProxyPort));
    Request request = new Request.Builder()
        .url("https://www.example.com")
        .proxy(currentProxy)
        .addHeader("referer", SomeReferrer)
        .addHeader("cache-control", "no-cache")
        .addHeader("pragma", "no-cache")
        .get()
        .build();
    // try-with-resources自动关闭响应,兜底释放连接
    try (Response response = GLOBAL_HTTP_CLIENT.newCall(request).execute()) {
        String body = response.body().string();
        // 处理业务逻辑
    } catch (IOException e) {
        // 异常处理逻辑
    }
    Thread.sleep(5000);
}
  1. 补充系统参数优化
    如果确认存在临时端口耗尽问题,调整系统内核参数扩大端口范围、允许复用TIME_WAIT状态连接即可:
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:45:05