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

Android4G 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

我们通过实现此接口,将解析到的 ip 顺序调整一下,如果是 ipv4 则将其放到数据的第一个,其它保持不变,如下图:


自定义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 审核时打开,审核完成后再关掉,这种不能解决根本问题的方法实在不可取,大家一定要仔细分析,擦亮眼睛

Android 在 4G 下访问 IPV6 慢的解决方案的更多相关文章

  1. ipv4-only网络环境下访问ipv6站点

    使用6plat.org+openVPN(无需资金投入)进入ipv6网络 这里我们主要使用的是6plat.org提供的“46模块——IPv4到IPv6”功能,需要配合openVPN这个软件,支持wind ...

  2. Android 在 SElinux下 如何获得对一个内核节点的访问权限

    点击打开链接 Android 5.0下,因为采取了SEAndroid/SElinux的安全机制,即使拥有root权限,或者对某内核节点设置为777的权限,仍然无法在JNI层访问. 本文将以用户自定义的 ...

  3. Android 在 SElinux下 如何获得对一个内核节点的访问权限【转】

    本文转载自:https://blog.csdn.net/wh_19910525/article/details/45170755 Android 5.0下,因为采取了SEAndroid/SElinux ...

  4. MAC 下使用ipv6、ipv4观看电视、网络电视

      换了mac book,ipv6电视却看不了了,为了看电视,只要自己动手了. 关于ipv6是啥和哪里有ipv6这里就不说了,找度娘吧. 我们观看IPv6视频直播信号有两种,一种是mms协议,另外一种 ...

  5. Django REST Framework学习——Android使用REST方法访问Diango

    本文更应该叫做Android如何模拟浏览器访问Django服务器后台. 环境为: Android通过HttpClient访问服务器,从Django中获取json数据,解析显示在UI界面上. 问题为: ...

  6. Android中的各种访问权限Permission含义

    android.permission.EXPAND_STATUS_BAR 允许一个程序扩展收缩在状态栏,android开发网提示应该是一个类似Windows Mobile中的托盘程序 android. ...

  7. 【转】非教育网中IPv4网络访问IPv6资源

    1. 背景知识 随着个人电脑.移动终端.乃至物联网的不断发展,有很大的IP地址需求.由于IPv4协议设计时没有料到日后网络会如此发达,IPv4网络中的IP数量相对今天的需求来说,显得捉襟见肘.加上IP ...

  8. Android中的资源访问

    Android中的资源是指非代码部分,指外部文件. assets中保存的一般是原生的文件,例如MP3文件,Android程序不能直接访问,必须通过AssetManager类以二进制流的形式来读取. r ...

  9. 校园网、教育网 如何纯粹访问 IPv6 网站避免收费

    我国校园网有可靠的 IPv6 网络环境,速度非常快.稳定,并且大多数高校在网络流量计费时不会限制 IPv6 的流量,也就是免费的.然而访问 IPv4 商业网络时,则会收费,并且连接的可靠性一般.可幸的 ...

随机推荐

  1. PRISM 4 - RegisterViewWithRegion & Custom Export Attributes

    5down votefavorite   I am using Prism 4 with MEF Extensions and the MVVM pattern. During initializat ...

  2. 文件分发服务器 AWS CloudFront(CDN)使用入门-以S3为例 Lebal:Research

    引言 在互联网上随意右击一张图片,都可以发现复制图片地址这个选项,这说明他们都有自己的链接(直链),也就是说我们可以通过一个链接本身来访问图片.代码等文件,而不是打开一个网页再选择复制,这就和下载链接 ...

  3. HTML DOM Document对象 元素对象 属性对象 事件对象

    DOM Document对象 DOM 元素 对象 DOM 属性 对象 DOM 事件 菜鸟教程上 总结挺全的,就不多废话,链接点进去即可.. 后期对经常用到的会在此更新一些总结..... 开学了...自 ...

  4. LeetCode.1033-移动石头直到连续(Moving Stones Until Consecutive)

    这是小川的第386次更新,第414篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第247题(顺位题号是1033).在a,b和c位置的数字线上有三块石头.每次,你在一个终点 ...

  5. nginx下配置vue前端项目

    server { listen 80; server_name _; root /opt/h5/index/; location / { index index.html index.htm inde ...

  6. 【转】mysql的group_concat函数,默认最大长度是1024

    mysql的group_concat函数,默认最大长度是1024 查询sql: show variables like 'group_concat_max_len'; 设置方式: 修改配置文件my.i ...

  7. Python 入门之 内置模块 --logging模块

    Python 入门之 内置模块 --logging模块 1.logging -- 日志 (1)日志的作用: <1> 记录用户信息 <2> 记录个人流水 <3> 记录 ...

  8. 认识react, 并简单与vue对比

    应用场景: 负责场景下的高性能 重用组件库,组件组合 中文官网:https://reactjs.org.cn/doc/in... 特点: 声明式编码(不需要关心如何实现,只需要关注在哪里做什么) 组件 ...

  9. 匿名函数lambda和map函数

    一.map函数,实现迭代操作 map(f1,x) f1为函数的名称(不加括号),x为map的参数,示例如下: def add(a): return a+10 print map(add,[1,2,3] ...

  10. KVM安装配置笔记

    系统环境centos6.6 一.KVM安装前系统相关操作: (1)修改内核模式为兼容内核启动 # grep -v "#" /etc/grub.confdevice (hd0) HD ...