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 审核时打开,审核完成后再关掉,这种不能解决根本问题的方法实在不可取,你们必定要仔细分析,擦亮眼睛
相关文章
相关标签/搜索