问题一:关于 OkHttp 请求延迟阻塞现象的解决记录
近期现场的设备出现了 loading 弹出异常的问题,通过排查日志,发现出现了很怪异的现象。
- 网络请求前的日志正常打印,网络请求拦截器中的日志延迟很久才打印,最多有13分钟之后才打印网络请求。
- 查服务器端日志,发现服务器也是13分钟之后接到的网络请求
- 怀疑是线程阻塞或者机器卡住,对多项并行操作增加线程池管理之后问题仍然出现。
- 查阅日志,在网络请求被延迟的这段时间,socket 正常。
最后通过查阅资料与源码,发现如果配置的 Dns 服务异常,会因为 okhttp 解析导致的网络请求延迟,而该代码在请求连接池之前,所以拦截器中的日志也没有执行。
更换Dns即可。
问题二:
脚本:
在没有互联网的情况下打开应用程序,该应用程序将尝试执行请求,但将失败
打开互联网连接,然后按下重试按钮以触发互联网请求
改装&okhttp总是给我HTTP失败:java.net.SocketTimeoutException:超时
从一开始就在启用互联网的情况下重新启动应用程序将使一切正常,除非我再次关闭它,并使请求失败,否则从那时起,它将给我同样的错误。我从来没有在Java上遇到过这个问题,只是在Kotlin上。
private val interceptor: Interceptor =
object : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var builder = chain.request().newBuilder()
Prefs.token?.let { token ->
builder = builder.addHeader("Authorization", "Bearer $token")
}
return chain.proceed(builder.build())
}
}
private val httpLoggingInterceptor: HttpLoggingInterceptor by lazy {
val interceptor = HttpLoggingInterceptor()
interceptor.level =
if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
interceptor
}
private val httpClient: OkHttpClient by lazy {
OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.addInterceptor(interceptor)
.build()
}
val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl("https://api.secret.com/v1/")
.addConverterFactory(GsonConverterFactory.create(gson))
.client(httpClient)
.build()
}
服务类是这样的
@GET("something")
fun something(): Call<SomeResponse>
我试过使用超时值,无论超时时间如何,我都会得到同样的错误。
为每个请求创建一个新的http客户端可以解决这个问题,但我认为这不是一个好主意。
网友回答:
您的问题看起来像OkHttp Bug。如果你点击链接,你会发现有很多可能的解决方案进行了长时间的讨论。
以下解决方案适用于我的项目:
- 1、将OkHttp更新至4.3.0版本。
2、设置ping间隔,例如1秒
okHttpClientBuilder.pingInterval(1, TimeUnit.SECONDS)
它是如何工作
问题的根源在于,Android操作系统无法提供任何方式来知道连接不再处于活动状态。因此,对于库连接来说,这看起来是有生命的,但它已经死了。因此,我们在每个请求上都会出现超时异常。一旦我们设置了ping,OkHttp就会开始发送ping帧,这样,若服务器并没有响应,库就会知道连接已经断开,是时候创建一个新的连接了。
不推荐解决方案,但应该有效
1、关闭连接池
okHttpClientBuilder.connectionPool(new ConnectionPool(0, 1, TimeUnit.NANOSECONDS))
2、使用Http 1.1
okHttpClientBuilder.protocols(listOf(Protocol.HTTP_1_1))
在这两种不推荐的解决方案中,您只需停止重复使用已经打开的连接,这会使每个请求的时间稍微长一点。
1
1
555
1
1
1
1
1
1
1
1
1
1
555
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
555
555
1
1
1
1
555
1
1
1
1
555
1
1
1
1
1
1
1
1
1
1
1
1
555
1
1
555
555
这篇文章写得深入浅出,让我这个小白也看懂了!
不错不错,我喜欢看
叼茂SEO.bfbikes.com
不错不错,我喜欢看 https://www.237fa.com/
想想你的文章写的特别好https://www.ea55.com/
不错不错,我喜欢看 www.jiwenlaw.com
你的文章内容非常卖力,让人点赞。http://www.rfyjade.com
你的文章内容非常卖力,让人点赞。http://www.shmaoren.com
你的文章内容非常卖力,让人点赞。http://www.shmaoren.com
你的文章内容非常专业,让人佩服。http://www.0427xt.com