OkHttpClient:IO问题排查

OkHttpClient:IO问题排查

问题描述

我们有个需求需要获取上传至oss图片的宽高信息,在原有文件链接后面加上后缀?x-oss-process=image/info,然后使用OkHttpClient组装get请求获取数据。在测试环境测试的时候,发现会出现偶现的IOException报错

java.io.IOException: unexpected end of stream on Connection{, proxy=DIRECT hostAddress= cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 protocol=http/1.1}

问题排查

  1. 通过搜索资料发现这个问题的解释:The error occurs when OkHttp try to reuse a connection that is in FIN_WAIT2 state in server,because the server keep_alive timeout is lesser than the client timeout.
    简单翻译下,可以知道是OkHttp重复使用了上一次处于FIN_WAIT2状态的连接,导致报错
  2. 那么在TCP三次握手中什么情况下会出现FIN_WAIT2这个状态:

主动一方发起FIN报文,只要对端发送ACK确认后主动方就会处于FIN_WAIT2状态,然后等待对端发送FIN报文,如果一直没有发送FIN报文(就会一直处于CLOSE_WAIT状态,还有数据要发送,等等再关闭),那么主动一方就可能永远处于FIN_WAIT2状态

问题解决

  1. 第一种解决方案:
    在http1.1中,client和server都是默认对方支持长链接的, 如果client使用http1.1协议,但又不希望使用长链接,则需要在header中指明connection的值为close;如果server方也不想支持长链接,则在response中也需要明确说明connection的值为close。不论request还是response的header中包含了值为close的connection,都表明当前正在使用的tcp链接在请求处理完毕后会被断掉。以后client再进行新的请求时就必须创建新的tcp链接了。
  2. 第二种解决方案:
    设置retryOnConnectionFailure=true,即连接失败时允许重连
OkHttpClient.Builder()
      .sslSocketFactory(sslSocketFactory(), x509TrustManager())
      .retryOnConnectionFailure(true)
      .connectionPool(pool())//连接池
      .connectTimeout(3L, TimeUnit.SECONDS)
      .readTimeout(3L, TimeUnit.SECONDS)
      .build();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值