okHttp 客户端在添加 callTimeout() 配置后超时,并且有时请求无法到达主机

问题描述 投票:0回答:3

将 callTimeout() 配置添加到 okhttp 客户端后,我开始超时

Caused by: java.io.InterruptedIOException: timeout
Caused by: java.io.IOException: Canceled

OkHttpClient httpClient = new OkHttpClient.Builder()
                .callTimeout(5_000L, TimeUnit.MILLISECONDS)
                .connectTimeout(500L, TimeUnit.MILLISECONDS)
                .readTimeout(5_000L, TimeUnit.MILLISECONDS)
                .writeTimeout(5_000L, TimeUnit.MILLISECONDS)
                .build();

我不完全确定将callTimeout配置为与write和read相同的值是否正确。是否有可能如果read和write需要更长的时间来触发callTimeout()? 另外一个奇怪的事情是,有时请求甚至没有到达主机

java android retrofit okhttp
3个回答
1
投票

添加配置后,您收到此异常,我怀疑,请求的端点需要比您配置的 5 秒更多的时间。

如果您请求的端点需要超过 5 秒(5_000 毫秒)才能获得响应,则使用此配置您将在此处遇到超时。

您可以使用postman获取您请求的端点的响应时间。如果超过5秒,您可以简单地相应配置这些值。也许,你可以用 30 秒,而不是 5 秒。

希望有帮助。


0
投票

callTimeOut()

设置完整调用的默认超时。值为 0 表示否 超时,否则值必须介于 1 和 [Integer.MAX_VALUE] 之间 当转换为毫秒时。调用超时跨越整个 调用:解析DNS、连接、写入请求体、服务器 处理并读取响应正文。如果通话需要 重定向或重试都必须在一个超时期限内完成。这 默认值为 0,不强制超时。

如果我错了,请纠正我。据我了解,

callTimeOut()
设置整个呼叫的呼叫超时跨度。例如:您设置
callTimeOut = 5s
。如果解析 DNS 需要 1 秒,连接 1 秒,写入 2 秒,读取 2 秒,那么您将得到 TimeOut 异常。默认情况下,callTimeOut() 设置为无超时,而另一个默认超时为 10 秒。为什么必须将 callTimeOut() 设置为 5 秒?对我来说,我以前从未设置过 callTimeOut。


0
投票

也有可能您超出了 CPU 配额。调用超时由侧线程(称为 Watchdog)控制,即在无限循环中检查特定请求调用超时是否已过期(源代码)。但是,当您创建大量线程并且所有线程都排队等待 CPU 时,调用超时可能会在它们在队列中等待时到期,因此它不依赖于网络。虽然读取和连接超时并不取决于线程在队列中太长的事实,因为这些超时是在操作系统级别进行管理的。

这也解释了为什么实际请求没有发送——因为请求线程在看门狗中注册后立即从 CPU 中移出。实际的请求还没有发送,但是看门狗已经确定时间已经过去了。

这就是为什么您不应该对后端应用程序使用这种超时,尤其是在云中工作。对于Android应用程序或其他客户端使用它更有意义。

© www.soinside.com 2019 - 2024. All rights reserved.