每天报告数千个与 OkHttp 相关的问题(连接、未知主机、DNS 等)

Sae*_* Oh 11 dns android kotlin retrofit okhttp

设置

我有一个正在生产中的应用程序,每天有数千名用户使用。

我使用的是 Retrofit2 版本 2.9.0(最新)

我的build.gradle下面。

def retrofitVersion = '2.9.0'
api "com.squareup.retrofit2:converter-gson:${retrofitVersion}"
api "com.squareup.retrofit2:converter-scalars:${retrofitVersion}"
api "com.squareup.retrofit2:adapter-rxjava2:${retrofitVersion}"
api "com.squareup.retrofit2:retrofit:${retrofitVersion}"
Run Code Online (Sandbox Code Playgroud)

我集成了 Firebase Crashlytics 并使其能够在try-catch块中报告任何与 API 相关的异常。

例如

def retrofitVersion = '2.9.0'
api "com.squareup.retrofit2:converter-gson:${retrofitVersion}"
api "com.squareup.retrofit2:converter-scalars:${retrofitVersion}"
api "com.squareup.retrofit2:adapter-rxjava2:${retrofitVersion}"
api "com.squareup.retrofit2:retrofit:${retrofitVersion}"
Run Code Online (Sandbox Code Playgroud)

已知

现在,在 Crashlytics 中,我每天都会收到数千份报告,称存在一些错误。在讨论这些错误之前,我想向您保证用户已使用适当的网络权限连接到互联网。我看到用户当时正在打开其他内容的日志。所以这些错误看起来确实是随机的。

埃罗斯

  1. 未知主机异常
Non-fatal Exception: java.net.UnknownHostException: Unable to resolve host "my-host-address.com": No address associated with hostname
       at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:156)
       at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
       at java.net.InetAddress.getAllByName(InetAddress.java:1152)
       at okhttp3.Dns$Companion$DnsSystem.lookup(Dns.java:5)
...
Caused by android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
       at libcore.io.Linux.android_getaddrinfo(Linux.java)
       at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
       at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:200)
       at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
       at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:135)
       at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
...
Run Code Online (Sandbox Code Playgroud)
  1. 连接异常
Non-fatal Exception: java.net.ConnectException: Failed to connect to my-host-address.com/123.123.123.123:443
       at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:146)
       at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:191)
       at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:257)
       at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java)
       at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:47)
...
Caused by java.net.ConnectException: failed to connect to my-host-address.com/123.123.123.123 (port 443) from /:: (port 0) after 10000ms: connect failed: ENETUNREACH (Network is unreachable)
       at libcore.io.IoBridge.connect(IoBridge.java:142)
       at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
       at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
       at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
       at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
       at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
       at java.net.Socket.connect(Socket.java:621)
...
Caused by android.system.ErrnoException: connect failed: ENETUNREACH (Network is unreachable)
       at libcore.io.Linux.connect(Linux.java)
       at libcore.io.ForwardingOs.connect(ForwardingOs.java:94)
       at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:138)
       at libcore.io.ForwardingOs.connect(ForwardingOs.java:94)
       at libcore.io.IoBridge.connectErrno(IoBridge.java:173)
       at libcore.io.IoBridge.connect(IoBridge.java:134)
...
Run Code Online (Sandbox Code Playgroud)
  1. 套接字超时异常
Non-fatal Exception: java.net.SocketTimeoutException: timeout
       at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.java:4)
       at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.java:8)
       at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.java:24)
       at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.java:5)
       at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.java:2)
       at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:145)
...
Run Code Online (Sandbox Code Playgroud)
  1. 另一个 SocketTimeoutException
Non-fatal Exception: java.net.SocketTimeoutException: SSL handshake timed out
       at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(NativeCrypto.java)
       at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387)
       at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:234)
       at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:72)
       at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:52)
       at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:196)
       at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:257)
       at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java)
       at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:47)
Run Code Online (Sandbox Code Playgroud)

最后,让我认为这不是我的服务器问题的是,当我向 Google 服务器请求横幅广告时,我也遇到了这种错误。我收到了数以千计的以下报告

{   "Message": "Error while connecting to ad server: Failed to connect to pubads.g.doubleclick.net/216.58.195.130:443",   "Cause": "null",   "Response Info": {     "Adapter Responses": [],     "Response ID": "null",     "Response Extras": {},     "Mediation Adapter Class Name": ""   },   "Domain": "com.google.android.gms.ads",   "Code": 0 }
Run Code Online (Sandbox Code Playgroud)

来自 Google ads SDK 的onAdFailedToLoad监听器。

试图

我试图在Retrofit2/OkHttp3 github issues、SO社区中找到一些解决方案,每个人都说可能存在一些网络权限问题或网络连接问题本身。但我知道用户已连接到互联网并且没有使用某种代理。我与客户服务团队合作,他们与用户一起进行了检查,他们没有发现任何网络问题。

任何见解都会有所帮助。先感谢您!

小智 0

大约两年前,我遇到了这样的问题。幸运的是,前面的答案不是我的情况(我在清除 DNS 缓存后尝试过)。我和我的 ISP 讨论了这个问题,他们说了一些关于缓存请求和响应的内容。他们还告诉我等待 24 小时,服务器/ISP 会释放缓存,然后再尝试。我等待着,结果成功了。我不知道这是怎么发生的,也不知道为什么会这样。