Android 在 4G 下訪問 IPV6 慢的解決方案

Android 在 4G 下訪問 IPV6 慢的解決方案

原由

今天,用戶反饋 Android 端加載數據較慢,經 Android 開發人員排查後,發如今公司 wifi 下接口響應時間在 50ms 左右,而在 4G 網絡下,接口響應時間在 600ms 左右,甚至於 1s 以上,Android 端認爲是服務端問題,遂反饋到服務端html

排查

  1. 首先檢查 nginx 日誌,發現無論是 wifi 網絡下仍是 4G 網絡下,服務端的響應時間均在 30ms 左右,因此排除掉了代碼的問題java

  2. 向運維同窗諮詢了一下服務端的網絡架構,原來爲了 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();
}
  1. 鏈接公司 wifi ,執行代碼,只解析到 ipv4 地址
  2. 使用 4G 網絡,執行代碼,解析到 ipv6 和 ipv4 兩個 ip 地址,且 ipv6 一直是首個 ip 地址

解決

經過上面的驗證,基本判定爲 4G 網絡下,Android 端經過 ipv6 鏈接的服務地址。
端的 http client 庫爲 okhttp , 查看 javadoc 後,提供了 DNS 接口,代碼以下:架構

DNS
DNS

咱們經過實現此接口,將解析到的 ip 順序調整一下,若是是 ipv4 則將其放到數據的第一個,其它保持不變,以下圖:app

自定義DNS
自定義DNS

修改 okhttp 的 dns 解析類,以下:運維

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.dns(new MyDns());
OkHttpClient client = builder.build();

再次測試,發現 Android 端的接口響應時間迴歸正常測試

備註

  1. 在測試過程當中,發現中國移動和中國電信的 4G 網絡 DNS 解析都會解析到兩個 IP 地址,而中國聯通的 4G 網絡只能解析到 ipv4 的址,手機型號是小米 note3
  2. 網上不少的方案都是將 ipv6 關掉,或者在 appstore 審覈時打開,審覈完成後再關掉,這種不能解決根本問題的方法實在不可取,你們必定要仔細分析,擦亮眼睛
相關文章
相關標籤/搜索