Android 在 4G 下访问 IPV6 慢的解决方案

Android 在 4G 下访问 IPV6 慢的解决方案

起因

今天,用户反馈 Android 端加载数据较慢,经 Android 开发人员排查后,发现在公司 wifi 下接口响应时间在 50ms 左右,而在 4G 网络下,接口响应时间在 600ms 左右,甚至于 1s 以上,Android 端认为是服务端问题,遂反馈到服务端

排查

  1. 首先检查 nginx 日志,发现不管是 wifi 网络下还是 4G 网络下,服务端的响应时间均在 30ms 左右,所以排除掉了代码的问题

  2. 向运维同学咨询了一下服务端的网络架构,原来为了 IOS 的 appstore 审核,服务端增加了 ipv6 支持,而 ipv6 的服务入口在美国,如下图:

网络架构
网络架构

所以怀疑 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 则将其放到数据的第一个,其它保持不变,如下图:

自定义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 审核时打开,审核完成后再关掉,这种不能解决根本问题的方法实在不可取,大家一定要仔细分析,擦亮眼睛
posted @ 2019-01-14 23:09  feshfans  阅读(10118)  评论(1编辑  收藏  举报