- N +

聊聊HTTPS环境DNS优化:美图App请求耗时节约近半案例

  12月22~23,GIAC全球互联网架构大会将于上海举行,本周新增阿里,京东、LinkedIn等多名讲师出席,参看文末了解更多详情。

  导读:移动互联网时代,APP 厂商之间的竞争非常激烈,而良好的用户体验是必须优先考虑的,美图产品以高颜值著称,对产品的用户体验非常重视。从技术的角度来看,客户端的体验优化当中 DNS 优化是非常关键的一环,怎么降低 DNS 的耗时,怎么减少域名劫持等问题,都是大家需要重点解决的研发问题。本文介绍美图 DNS 优化的实践,作者从原理到效果,整体讲解的非常全面,值得学习和借鉴。

  DNS 查询时,会先在本地缓存中尝试查找,如果不存在或是记录过期,就继续向 DNS 服务器发起递归查询,这里的 DNS 服务器一般就是运营商的 DNS 服务器。

  美图的移动端产品在实际用户环境下会面临 DNS 劫持、耗时波动等问题,这些 DNS 环节的不稳定因素,导致后续网络请求被劫持或是直接失败, 对产品的用户体验产生不好的影响。

  为此,我们对移动端产品的 DNS 解析进行了优化探索,产生了相应的 SDK。在这过程中,我们参考借鉴了业内的主流方案,也进行了一些实践上的思考。

  解析转发 & 出口 NAT: 运营商 DNS 转发查询请求或是出口 NAT 导致流量调度策略失效;

  为了解决 LocalDNS 的这些问题,业内也催生了 HTTP DNS 的概念,它的基本原理如下:

  原本用户进行 DNS 解析是向运营商的 DNS 服务器发起 UDP 报文进行查询,而在 HTTP DNS 下,我们修改为用户带上待查询的域名和本机 IP 地址直接向 HTTP WEB 服务器发起 HTTP 请求,这个 HTTP WEB 将返回域名解析后的 IP 地址。

  根治域名解析异常: 绕过运营商的 DNS,向具备 DNS 解析功能的 HTTP WEB 服务器发起查询;

  美图的产品线丰富,涉及的域名也较为广泛,为了适应各产品的实际场景,在实践中我们设计了较为灵活的策略控制。

  一个 App 涉及的域名众多,在策略上我们能够配置其核心 API 域名走 HTTP DNS,而对于非核心请求我们仍希望它先尝试走 LocalDNS, 在异常情况下才升级走 HTTP DNS。

  IP 记录的 TTL 时间: 在 DNS 劫持发生的情况下,返回的 TTL 可能会有非常大的值;

  返回的 IP 的可连接性: 对返回的 IP 进行质量测试,如果连接状况不佳,那么这个 DNS 服务器有劫持的可疑;

  在 Android 平台上,通过系统方法获得的解析结果信息是非常有限的,上面的指标有的将无法获取,因此在实践中我们会自己去构造 DNS 查询报文,向运营商的多个 DNS 服务器发起查询。

  通过上面几个指标的综合评定,当 LocalDNS 表现不佳的时候,策略上我们将升级走 HTTP DNS,尝试让用户获取更好的 DNS 解析效果。

  LocalDNS 在过期的情况下,会发起递归查询,这个时间是不可控的,在部分情况下甚至能达到数秒级别; HTTP DNS 相对会好一些,但正常来看,也会有200ms 左右的耗时。 这个时间能否再优化一些呢?

  我们 SDK 在本地构建了自己的记录缓存池,每次通过 LocalDNS 或是 HTTP DNS 解析得到记录都存在缓冲池中。

  区别在于我们做了一个小改动:对于过期的记录我们采用懒更新的策略,当查到过期的缓存记录时,先返回过期记录给用户,同时再异步重新发起 DNS 查询更新缓存记录。

  这个小改动能够保证我们二次解析时都能命中本地缓存,极大地降低 DNS 解析耗时,不过它也带来了一定的风险性。

  因此实践中,我们也会添加异步定期的 DNS 记录缓存池扫描功能,及时发现缓存中的过期记录并进行更新,也降低 App 命中过期记录的情况。

  在 DNS 优化的实践中,我们遇到最大的问题,倒不是策略层面设计问题,而是我们的 DNS SDK 运用到实际 App 产品业务上的姿势问题。

  即原本直接请求 ,现在我们先调用 SDK 进行域名解析,拿到 IP 地址比如 1.1.1.1,然后替换域名为: ;

  这样操作之后, 由于 URL 中 HOST 已经是 IP 地址,网络请求库将跳过域名解析环节,直接向 1.1.1.1 服务器发起 HTTP 请求。

  首先,对于 HTTP 请求,采用 IP 直连的方案后,我们还是需要进行的一个操作是手动配置 Header 中的 HOST :

  在我们采用 IP 直连的形式后,上述 HTTPS 的第三步会发生问题, 客户端检验服务端下发的证书这动作包含两个步骤:

  证书的验证需要这两个步骤都检验通过才能够进行后续流程,否则 SSL/TLS 握手将在这里失败结束。

  由于在 IP 直连下,我们给网络请求库的 URL 中 host 部分已经被替换成了 IP 地址,

  因此证书验证的第二步中,默认配置下 “本次请求的 HOST” 会是一个 IP 地址,这将导致 domain 检查不匹配,最终 SSL/TLS 握手失败。

  解决 SSL/TLS 握手中域名校验问题的方法在于我们重新配置 HostnameVerifier, 让请求库用实际的域名去做域名校验,

  SNI(Server Name Indication)是为了解决一个服务器使用多个域名和证书的SSL/TLS扩展。它的基本工作原理如下:

  服务端配置有多个域名和对应的证书。客户端在与服务器建立SSL链接之时,先发送自己要访问站点的域名。

  跟上面 Domain 校验的情况类似,这里的网络请求库默认发送给服务端的 要访问站点的域名 就是我们替换后的 IP 地址。

  服务端在收到这样一个 IP 地址形式的域名后将是一脸懵逼,找不到对应的证书,最后只好下发一个默认的域名证书回来。

  接下来发生的是,客户端在检验证书的 Domain 域时,怎么也检查不通过,因为服务端下发的证书本来就不是对应该域名的。

  可以解决,需用客户端重新定制 SSLSocketFactory , 不过修改的代码相对较多,这里就不列举了。

  如果我们 SDK 要接入到 App 实际业务中,到 HTTPS SNI 场景处理这里,相信很多同学都崩溃了,接入的工作量其实也不低。

  很多情况下可能就做了妥协,只有 Okhttp 场景才使用这个 SDK,因为 Okhttp 本身支持 DNS 替换,没有上面那些问题。

  在美图的实践中,我们不仅仅希望 Okhttp 的请求才进行这个 DNS 优化,我们希望在 App H5 页面加载、播放器播放等场景也能应用相应的优化。

  在最初的实践中,我们也的确尝试了落实 IP 直连 到各个模块,然而即使克服了改造的工作量问题,实际运行上还是会有不少坑。

  那么,有没有更合适的一种技术方案,能够降低 我们 DNS SDK 的接入工作量,也能兼顾各种使用场景,比如 HTTPS、RTMP 协议等?

  基于这样的目标,我们在实践中尝试探索了一种对业务集成友好的无侵入式 DNS SDK 集成方案。下面我们以 Android 平台进行说明。

  这个偷天换日的操作之后,HttpsUrlConnection 等 Java 层网络请求在进行 DNS 解析时就会是这样一个流程:

  通过这个形式,我们能够完美解决 Java 层的 DNS SDK 接入问题,对于业务方来说,他们并不需要做任何 URL 替换操作,对应的 HTTPS 场景下的问题也不复存在。

  我们知道在 Android 平台上,像 WebView、播放器等模块他们进行网络连接的操作都是在 native 层进行的,并不会调用到 Java 层的 InetAddress 方法。

  另外我们还知道,在 Android 等 Linux 系统下,对于 .so 这类可共享对象文件会是 ELF 的文件格式。

  .rel.plt 表中的映射关系为 a.so 的运行指出了 getaddrinfo 这个外部符号在当前内存空间中的绝对地址。

  那么在这里,我们是否可以手动修改这个映射表内容,把 getaddrinfo 的内存地址替换成我们的 my_getaddrinfo 地址呢?

  实际上,确实是可行的。 我们尝试在 SDK 启动后,对 a.so 的 .rel.plt 表进行修改,达到接管 a.so DNS 的目的,

  通过上面的方式,我们能够比较完美地接管 App 在 Java 层 和 Native 层 DNS 过程,实现业务方无任何额外改动的情况下运用我们的 DNS SDK 优化效果。

  在实际运用中,我们取得了比较好的效果。得益于 DNS SDK 在命中本地缓存率上的策略优化,我们的移动端产品在网络请求中 DNS 解析环节耗时得到降低,

  通过 HTTP DNS 的引入和 LocalDNS 优化升级策略,我们的网络请求成功率有提升,在未知主机等具体错误率表现出下降的趋势。

  由于 SDK 层面本身做好了灵活的策略配置,我们通过线上监控和配置也让各产品在效益和成本之间取得一个最佳的平衡点。

  美图架构,专注于虚拟化平台建设、流媒体、云存储、千万同时在线的通讯服务、音视频编解码等基础设施建设,现急需相关领域爱好者加入,工作地点可自由选择北京、厦门、深圳,待遇从优,美女多多。现紧缺岗位如下:

  美图技术沙龙深圳站于12月底开启,欢迎关注官方公众号,关注最新动向。微信号: MTtechsalon

  12 月 22 ~ 23 日,GIAC 全球互联网架构大会将于上海举行。GIAC 是高可用架构技术社区推出的面向架构师、技术负责人及高端技术从业人员的技术架构大会。GIAC 于 2016 年 12 月成功举办了第一届,今年的 GIAC 已经有腾讯、阿里巴巴、百度、平安、饿了么、携程、七牛、蚂蚁金服、罗辑思维、摩拜、唯品会,LinkedIn, Pivotal, Mesosphere, AdMaster, Hulu 等公司专家出席。

  参加 GIAC,盘点年底最新技术,目前单人购买优惠 600 元,多人购买有更多优惠。返回搜狐,查看更多

返回列表
上一篇:
下一篇:
评论列表 (暂无评论,共812人参与)

还没有评论,来说两句吧...

发表评论

验证码