OkHttpClient请求约三分之一失败报unexpected end of stream异常原因咨询
unexpected end of stream异常的排查方向 这种间歇性的异常(约三分之一请求触发)在OkHttp的使用场景里挺常见的,而且和你禁用证书验证关系不大——毕竟你已经跳过了证书校验环节,证书问题不会以这种流中断的形式表现。下面是几个最可能的原因和对应的排查思路:
服务器端主动关闭空闲连接
OkHttp默认会复用HTTP连接(基于HTTP/1.1的keep-alive机制),如果服务器的keep-alive超时时间比OkHttp连接池的空闲连接存活时间短,当OkHttp尝试复用一个已经被服务器主动关闭的连接时,就会抛出这个异常。
你可以尝试调整OkHttp连接池的参数,缩短空闲连接的存活时间,让它早于服务器的超时时间:ConnectionPool connectionPool = new ConnectionPool( 5, // 最大空闲连接数 30, TimeUnit.SECONDS // 空闲连接存活时间 ); OkHttpClient client = new OkHttpClient.Builder() .connectionPool(connectionPool) .build();同时也可以联系服务器端团队,确认他们的keep-alive配置是否合理。
网络中间设备中断连接
代理、防火墙、CDN这类网络中间设备,往往会有自己的连接超时或清理策略,比如主动切断长时间空闲的连接,或者因负载过高强制中断连接。这种情况下,OkHttp复用连接时就会遭遇流意外结束。
你可以临时禁用连接复用做个验证(虽然会降低性能,但能快速定位问题):Request request = new Request.Builder() .url("你的请求地址") .header("Connection", "close") // 告诉服务器不要复用这个连接 .build();如果禁用后异常消失,基本可以确定是中间设备的问题,这时候需要和运维团队配合调整网络设备的策略。
服务器端响应不完整
如果服务器在处理请求过程中突然崩溃、抛出未捕获异常,或者因资源不足(比如OOM)终止响应,OkHttp在读取响应流时就会遇到“意外结束”的情况。
这种情况需要和服务器端团队配合,查看服务器的日志,排查请求处理时是否有异常记录,比如报错、堆栈信息等。OkHttp版本存在bug
某些旧版本的OkHttp在连接复用、异常处理逻辑上可能存在漏洞,比如没有正确清理已失效的连接。你可以尝试升级到最新的稳定版OkHttp(目前是4.x系列),很多这类历史bug已经被修复。客户端超时配置不合理
虽然这种情况更多会抛出SocketTimeoutException,但如果你的connectTimeout、readTimeout或writeTimeout设置得过短,或者服务器响应速度不稳定,也可能间接导致流中断异常。你可以适当调大超时时间,看看是否能缓解问题:OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build();
内容的提问来源于stack exchange,提问作者Aleksey Khokhrin

