今天,用戶反饋 Android 端加載數據較慢,經 Android 開發人員排查後,發如今公司 wifi 下接口響應時間在 50ms 左右,而在 4G 網絡下,接口響應時間在 600ms 左右,甚至於 1s 以上,Android 端認爲是服務端問題,遂反饋到服務端html
首先檢查 nginx 日誌,發現無論是 wifi 網絡下仍是 4G 網絡下,服務端的響應時間均在 30ms 左右,因此排除掉了代碼的問題java
向運維同窗諮詢了一下服務端的網絡架構,原來爲了 IOS 的 appstore 審覈,服務端增長了 ipv6 支持,而 ipv6 的服務入口在美國,以下圖:nginx
因此懷疑 Android 端解析域名時解析到兩個 IP 後,優先使用 IPV6 鏈接的後端服務後端
使用以下代碼,驗證 DNS 解析的 IP 地址網絡
try { InetAddress[] inetAddresses = InetAddress.getAllByName("server.xxxx.cn"); for(InetAddress inetAddress : inetAddresses){ System.out.println(inetAddress.getHostAddress()); } } catch (UnknownHostException e) { e.printStackTrace(); }
經過上面的驗證,基本判定爲 4G 網絡下,Android 端經過 ipv6 鏈接的服務地址。
端的 http client 庫爲 okhttp , 查看 javadoc 後,提供了 DNS 接口,代碼以下:架構
咱們經過實現此接口,將解析到的 ip 順序調整一下,若是是 ipv4 則將其放到數據的第一個,其它保持不變,以下圖:app
修改 okhttp 的 dns 解析類,以下:運維
OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.dns(new MyDns()); OkHttpClient client = builder.build();
再次測試,發現 Android 端的接口響應時間迴歸正常測試
- 在測試過程當中,發現中國移動和中國電信的 4G 網絡 DNS 解析都會解析到兩個 IP 地址,而中國聯通的 4G 網絡只能解析到 ipv4 的址,手機型號是小米 note3
- 網上不少的方案都是將 ipv6 關掉,或者在 appstore 審覈時打開,審覈完成後再關掉,這種不能解決根本問題的方法實在不可取,你們必定要仔細分析,擦亮眼睛