OkHttp3超时配置异常求助:设4分钟却2分钟触发SocketTimeoutException
我之前也碰到过一模一样的坑!当时折腾了好半天,总结了几个最常见的原因和对应的解决办法,你可以逐一排查:
检查中间代理/网关的超时设置
很多公司的Nginx、负载均衡器或者API网关会自带超时限制,比如Nginx默认的proxy_read_timeout就是2分钟。这时候哪怕你客户端把超时设得再长,中间件会先断开连接,直接导致你收到SocketTimeoutException。赶紧去确认这些中间服务的超时配置,把它们的超时时间调整到比你设置的4分钟更长(比如5分钟)。验证OkHttp的超时配置是否真正生效
有时候代码里可能存在多处OkHttpClient的初始化逻辑,或者某个地方覆盖了你原本的超时设置。建议在发起请求前,打印出客户端的超时参数做验证:OkHttpClient client = yourClientInstance; System.out.println("连接超时: " + client.connectTimeoutMillis() + "ms"); System.out.println("读取超时: " + client.readTimeoutMillis() + "ms"); System.out.println("写入超时: " + client.writeTimeoutMillis() + "ms");确保输出的数值都是240000ms(也就是4分钟),如果不是,就得找到哪里的配置被覆盖了。
区分异常类型,排查服务端侧的超时
仔细看SocketTimeoutException的异常栈信息,它会明确告诉你是连接超时还是读取超时。如果是读取超时,大概率是服务端那边也设置了超时时间,在2分钟的时候主动断开了连接。这时候需要和服务端开发同学确认他们的接口处理超时配置,调整到匹配你的客户端超时时间。检查重试机制的影响
OkHttp默认开启了连接失败重试(retryOnConnectionFailure(true)),有时候重试的累计时间可能会让你误以为是第一次请求在2分钟超时。你可以先临时关闭重试试试,看是否还会出现这个问题:OkHttpClient client = new OkHttpClient.Builder() .retryOnConnectionFailure(false) .connectTimeout(4, TimeUnit.MINUTES) .readTimeout(4, TimeUnit.MINUTES) .writeTimeout(4, TimeUnit.MINUTES) .build();排查系统层面的TCP超时(少见但需注意)
某些操作系统的TCP层面有默认的超时设置,比如Linux的net.ipv4.tcp_keepalive_time等参数。不过这个一般默认值远大于2分钟,所以优先级靠后排查。如果前面的方法都没用,可以去查一下系统的网络参数配置。
按这个顺序排查下来,大概率能找到问题所在!
内容的提问来源于stack exchange,提问作者Alice

