什么叫ipv6网络_IPv6 下 Happy Eyeballs 的最佳实践

前言

IPv6 是当下如火如荼的话题,由于 IPv4 地址的耗尽,所以 IPv6 的切换已经势在必行。但在 IPv6 的初期,由于基础建设还不完善,IPv6 可能会出现连通性或可靠性的问题,那我们该如何从 IPv4 平稳过渡到 IPv6 呢?

目前业内标准的做法叫 Happy Eyeballs,什么叫 Happy Eyeballs 呢?就是不会因为 IPv4 或 IPv6 的故障问题,导致用户的眼球一直在等待加载或者出错,这就是 Happy Eyeballs 名字的由来。

背景

Happy Eyeballs 解决的核心问题是,复杂环境下 v4 和 v6 IP 选取的问题,它是一套整体解决方案,对于域名查询的处理,地址的排序,连接的尝试等方面均做出了规定。

Happy Eyeballs 有 v1 版本 RFC6555(Cisco 提出来的)和 v2 版本 RFC8305(Apple 提出来的)。具体的协议规范可参考资料【1】和【2】。我们从百度 App 对于 Happy Eyeballs 的实践出发,剖析下百度 App 是如何实现 Happy Eyeballs 的。

最佳实践

百度 App 的 Happy Eyeballs 最佳实践,如下图所示。

6d49da0c79dfb3acf4d468f7d671683e.png

Happy Eyeballs 最佳实践

最佳实践包括自有业务和核心组件(图片库,播放内核,浏览内核)底层网络库的流量接管。

网络库包括 ijkavformat(ijkplayer 的网络模块,实现了 RFC8305 的 Happy Eyeballs),okhttp(实现了 RFC6555 的 Happy Eyeballs),统一网络库 cronet(实现了 RFC6555 的 Happy Eyeballs)。

下面我们来看下这三个网络库的 Happy Eyeballs 的实现机制。

丨 1. ffmpeg(ijkplayer 不准确) 的 Happy Eyeballs 实现机制

我们从域名查询的处理,地址的排序,连接的尝试三个方面来说明。

dfce11641a597e4c60c06d79445e7d4f.png

ijkplayer Happy Eyeballs 实现机制

域名查询的处理,百度 App 的 ijkplayer 主要流量走的是 localDNS,会将 v4 和 v6 地址一并查询回来,DNS query 中 A 记录表示 v4 查询,Type 是 1,AAAA 记录表示 v6 查询,Type 是 28。具体协议可以参考下面两图。

e31624af8dd6616d4c88360f814b32b9.png

IPv4 的 Query

5958c323e84d982cc3e092fbbf081666.png

IPv6 的 Query

地址的排序,如果查询回来是多个 v4 和 v6 的地址,会将查询结果保存在 addrinfo 这个结构体里,它是一个链表结构,会将这个链表交替排序,v6 在前,v4 在后,比如查询回来的是 [第一个 v4 地址,第二个 v4 地址,第一个 v6 地址,第二个 v6 地址],排序之后变成 [第一个 v6 地址,第一个 v4 地址,第二个 v6 地址,第二个 v4 地址]。

连接的尝试,立即连接 v6 地址,ijkplayer 可以让使用者设置连接超时时间,会将这个超时时间和 200ms(这是 RFC8305 建议的值)进行取小操作,如果在较小值以内 v6 建连成功,则结束,若以外将发起下一个 v4 连接,与此同时关闭当前的 v6 连接。延迟连接 v4 地址将重复上面的操作,如果成功则结束,如果超时将发起下一个 v6 连接,与此同时关闭当前的 v4 连接。直到没有 ip 地址。

丨 2. cronet 的 Happy Eyeballs 实现机制

我们从域名查询的处理,地址的排序,连接的尝试三个方面来说明。

8e22cc19ee801c01d7c606f002a5b460.png

cronet Happy Eyeballs 实现机制

域名查询的处理,百度 App 的 cronet 主要流量走的是 HTTPDNS,HTTPDNS 请求会将一个域名的 v4 地址和 v6 地址同时返回。

地址的排序,cronet 开启 Happy Eyeballs 有两个条件,一是查询结果第一个地址是 v6 的,二是查询结果里包含 v4 和 v6 的地址。cronet 会优先将 v6 地址放入结果列表,保证了第一点。

连接的尝试,立即连接 v6 地址并开启一个延迟 300ms(这是 RFC6555 建议的值)发起 v4 的建连的任务,如果在 300ms 以内 v6 建连成功,延迟任务直接终止,流程结束。若以外会将结果列表进行 rotate,按顺序将列表里的第一个 v4 地址旋转到第一个,发起 v4 连接,此时将开启一个竞争模式,当 v4 开始建立连接和建连成功后,都会去检查 v6 是否成功,只要 v6 在竞争模式内建连成功,则使用 v6 的连接,v6 没有建连成功,则使用 v4 连接。

丨 3. okhttp 的 Happy Eyeballs 实现机制

71212d6045f703856483e7d74d3fa88f.png

okhttp Happy Eyeballs 实现机制

百度 App 依照 cronet 的实现细节,遵循 RFC6555 的规范,实现了 okhttp 版本的 Happy Eyeballs,由于实现细节和 cronet 类似,所以就不在这里进行讲解。

主体流程如上图,通过 okhttp 的请求并发控制模块(核心定义了最大线程数 64 个和单域名的最大并发数 5 个),再来到核心拦截器模块,包括对于 Header 和 Cookie 处理的拦截器,对于 Cache 处理的拦截器,对于连接处理的拦截器,在连接处理的拦截器里首先是从连接池获取连接,获取不到就会新创建连接,Happy Eyeballs 的实现就会加到这里。

丨 4. WKWebView 的 Happy Eyeballs 实现

在某些场景下 WKWebView 没有被 cronet 网络库进行接管,所以还需要依赖苹果自身的 Happy Eyeballs 机制,在这里就不多赘,感兴趣的同学可以参考资料【3】,苹果的工程师会详细讲解如何实现 Happy Eyeballs 的机制以及 Happy Eyeballs 下走 v6 的测试结果。

结语

IPv6 的进程是任重而道远的,Happy Eyeballs 做为从 v4 过渡到 v6 的重要规范必然会起到它应有的使命,详尽了解它并使用它应该是每个相关工程师的职责,希望本次番外篇对大家有帮助,感谢大家的辛苦阅读。

本文转载自公众号百度 App 技术。

原文链接

https://mp.weixin.qq.com/s?__biz=MzUxMzk2ODI1NQ==&mid=2247483915&idx=1&sn=ce1140c3911f2e202a693726116b174d&chksm=f94c531bce3bda0d85134f9647aab58b92c50552d6b694470807dc005ca2c5c9acb2ca7928a5&scene=27#wechat_redirect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值