性能优化(1)- DNS

397 阅读5分钟

DNS全称Domain Name System,中文名称 - 域名系统,是万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP。

在输入域名到页面渲染完成的第一步就是进行DNS解析,所以了解什么是DNS及其解析流程是提升性能优化的重要一步。

DNS解析流程

我们首先用dig命令来了解一下 DNS 是怎么做域名解析的。

dig www.meituan.com

看下标注的红框,从左到右依次是:

  1. 访问的域名地址。
  2. 网络类型,DNS协议在设计的时候考虑到了其他网络类型,但是目前位置这个值还是写死的IN,这里可以理解成是互联网。(这个值目前一般不会变)
  3. 标识域名对应何种类型的地址,A 就代表ip的地址。

细心的同学可能会发现我明明输入的是www.meituan.com,但是这里却显示的www.meituan.com. ,为什么会多了一个 “.” ?

这里说明一下:

  • 末尾的 . 代表的是根域名,每个域名都有根域名。
  • 根域名的下一级叫顶级域名,比如我们熟知的.com与.cn等等。
  • 再下一级就是次级域名了,比如例子中的.meituan。这个次级域名只要你有钱是可以随便注册的。
  • 最后这个****www**,这个代表三级域名**。一般是用户在自己的域里面为服务器分配的名称。用户可以随便分他。 (比如m.meituan.com代表移动端域名地址)

大概了解了域名的结构,我们来详细看一下它的解析过程,我们利用 dig +trace 命令来看详细流程:

从上图我们可以很清晰的看到dns解析的过程是从右向左:

. -> .com -> meituan.com. -> www.meituan.com. -> IP
  1. 请求根域名服务器,带着 www.meituan.com.,根域名服务器发现是 .com 结尾,然后告诉你,我只知道 com顶级域名服务器的IP地址,你去问问它试试。

  2. 然后浏览器就向com顶级域名服务器请求,带着 www.meituan.com.,com顶级域名服务器只知道 meituan.com 所在的服务器的IP地址,然后告诉你去问问它试试。

  3. 然后就向 "美团公司域名服务器" 请求,带着 www.meituan.com. ,美团公司自己肯定知道 www 是个啥,所以就把最后真正的IP地址,返回给浏览器,到此,迭代查询完成了。

DNS优化方法

上个片段是 DNS 解析的一个大致过程,即 迭代解析 ,但不是很详尽,一个完整的 DNS 解析过程如下:

  1. 浏览器会从自身的DNS缓存中去查找(chrome://net-internals/#dns),没有找到则进行下一步

  2. 浏览器会从操作系统里的DNS缓存中找,windows系统中,命令行 ipconfig/displaydns 查看,linux上的NSCD(name service cache daemon)缓存服务,没有找到则进行下一步

  3. 从计算机hosts文件里找,没有找到则进行下一步

  4. 向你的 ISP(互联网服务提供商) 相关的 DNS servers(可以认为是你的网络接入服务器商提供,比如中国电信,中国移动,阿里云等域名供应商),如果这些服务器有缓存,则直接返回。这就是所谓的递归查询,意思就是能够直接返回对应的IP地址。一般80%到这里就可以了。如果还没有找到则进行下一步

  5. 通过上述步骤没有得到你想要的IP地址,那么就会按照上个片段进行迭代查询了,即会先从 root nameservers 找起,直到找到最终的IP。

从上面的过程可以看到,DNS解析是一个很复杂的过程,如果每次都经历递归查询和迭代查询,DNS的消耗是非常大的,尤其在移动端的2G、3G网络。

在大多数性能优化中,我们采用域名发散(静态资源配置多个cdn地址)的方式,目的是充分利用浏览器的多线程并发下载。

上图是各浏览器允许对每个域名的连接数的限制,基本都处于4-8个,然而这种方式却会给浏览器带来DNS解析的开销。

优化一:域名收敛

通过上面的过程来看,单纯的进行域名发散虽然增加了资源请求的连接数,但是却带来了额外的dns解析开销。

这里我们引入HTTP2,http2是以数据帧的形式进行传输,代替了http1.X的明文传输,原本的报文消息被划分为多个数据帧。把 HTTP/1.1 每个请求都当作一个流,那么多个请求变成多个流,请求响应数据分成多个帧,不同流中的帧交错地发送给对方,这就是 HTTP/2 中的多路复用。

流的概念实现了单连接上多请求 - 响应并行,减少了 TCP 连接数量。所以 http2 对于同一域名只需要创建一个连接,消除了因多个请求带来的DNS解析问题。

优化二:DNS 预解析

通常我们会利用DNS Prefetch进行预解析,DNS Prefetch 是对网页性能优化的一个通用方案,使用简单方便,如下图:

考虑到实际上webview和App自身代码使用的DNS缓存都是操作系统中的同一块存储区域,我们也可以统计出我们常用web页面中频繁请求的url的域名,在App一启动的时机,就提前访问这些域名,这样等到业务web页面在加载的时候,如果操作系统DNS缓存已经有了对应的ip,则可以省略一次DNS的查询。