网络协议私人订制的DNS服务:需要HTTPDNS 吗?( 二 )


HTTPDNS 的工作流程接下来,我们一起来认识下 HTTPDNS 的工作流程 。
HTTPDNS 会在客户端的 SDK 里动态请求服务端,获取 HTTPDNS 服务器的 IP 列表,缓存在本地 。随着不断地解析域名,SDK 也会在本地缓存 DNS 域名解析的结果 。
当手机应用要访问一个地址的时候,首先看是否有本地的缓存,如果有直接返回 。这个缓存和本地 DNS 的缓存不一样的是,这个是手机应用自己做的,而非整个运营商统一做 。如何更新以及何时更新缓存,手机应用的客户端可以和服务器协调来做这件事情 。
如果本地没有,就需要请求 HTTPDNS 的服务器,在本地 HTTPDNS 服务器的 IP 列表中,选择一个发出 HTTP 请求,获取一个要访问的网站的 IP 列表 。
手机客户端知道手机在哪个运营商、哪个地址 。由于是直接的 HTTP 通信,HTTPDNS 服务器能够准确知道这些信息,因而可以做精准的全局负载均衡 。

网络协议私人订制的DNS服务:需要HTTPDNS 吗?

文章插图
上面五个问题,归结起来就两大问题 。一是解析速度和更新速度的平衡问题,二是智能调度的问题 。HTTPDNS 对应的解决方案是 HTTPDNS 的缓存设计和调度设计 。
HTTPDNS 的缓存设计解析 DNS 过程复杂,通信此时多,对解析速度造成很大影响 。为了加快解析,因而有了缓存,但是这又会产生缓存更新速度不及时的问题 。最要命的是,这两个方面都掌握在别人手中,也就是本地 DNS 服务器手中,它不会为你定制,作为客户端干着急也没办法 。
而 HTTPDNS 就是将解析速度和更新速度全部掌控在自己手中 。
一方面,解析的过程,不需要本地 DNS 服务递归的调用一大圈,一个 HTTP 的请求直接搞定 。要实时更新的时候,马上就能起作用 。
另一方面,为了提高解析速度,本地也有缓存,缓存是在客户端 SDK 维护的,过期时间、更新时间,都可以自己控制 。
HTTPDNS 的缓存设计策略也是咱们做应用架构中常用的缓存设计模式,也即分为客户端、缓存、数据源三层 。
  • 对于应用架构来讲,就是应用、缓存、数据库 。常见的是 Tomcat、redis、MySQL;
  • 对于 HTTPDNS 来讲,就是手机客户端、DNS 缓存、HTTPDNS 服务器 。

网络协议私人订制的DNS服务:需要HTTPDNS 吗?

文章插图
只要是缓存模式,就存在缓存的过期、更新、不一致的问题,解决思路也是相似的 。
例如,DNS 缓存在内存中,也可以持久化到存储上,从而 App 重启之后,能够尽快从存储中加载上次累积的经常访问的网站的解析结果,就不需要每次都全部解析一遍,再变成缓存 。这有点像 Redis 是基于内存的缓存,但是同样提供持久化的能力,使得重启或者主备切换的时候,数据不会完全丢失 。
SDK 中的缓存会严格按照缓存过期时间,如果缓存没有命中,或者已经过期,而且客户端不允许使用过期的几率,则会发起一次解析,保证缓存记录是更新的 。
解析可以同步进行,也就是直接调用 HTTPDNS 的接口,返回最新的记录,更新缓存 。也可以异步进行,添加一个解析任务到后台,由后台任务调用 HTTPDNS 的接口 。
同步更新的优点是实时性好,缺点是如果有多个请求都发现过期的时候,会同时请求 HTTPDNS 多次,造成资源浪费 。
同步更新的方式对应到应用架构缓存的 Cache-Aside 机制,也就是先读缓存,不命中读数据库,同时将结果写入缓存 。
网络协议私人订制的DNS服务:需要HTTPDNS 吗?

文章插图
异步更新的优点是,可以将多个请求都发现过期的情况,合并为一个对于 HTTPDNS 的请求任务,只执行一次,减少 HTTPDNS 的压力 。同时,可以在即将过期的时候,就创建一个任务进行预加载,防止过期之后再刷新,称为预加载 。
它的缺点是,当前请求拿到过期数据的时候,如果客户端允许使用过期时间,需要冒一次风险 。这次风险是指,如果过期的请求还能请求,就没问题,如果不能请求,就会失败一次,等下次缓存更新后,才能请求成功 。
网络协议私人订制的DNS服务:需要HTTPDNS 吗?

文章插图
异步更新的机制,对应到应用架构缓存的 Refresh-Ahead 机制,即业务仅仅访问缓存,当过期的时候定期刷新 。在著名的应用缓存 Guava Cache 中,有个 RefreshAfterWrite 机制,对于并发情况下,多个缓存访问不命中从而引发并发回源的请求,可以采取只有一个请求回源的模式 。在应用架构的缓存中,也常常用数据预热或者预加载的机制 。


推荐阅读