DNS预解析详解

前言

DNS解析时间可能导致大量用户感知延迟,DNS解析所需的时间差异非常大,延迟范围可以从1ms(本地缓存结果)到普遍的几秒钟时间。所以利用DNS预解析是有意义的。

DNS与域名解析

DNS全称为Domain Name System,即域名系统,是域名和IP地址相互映射的一个分布式数据库。

域名解析即通过主机名,最终得到该主机名对应的IP地址的过程。

浏览器对网站第一次的域名DNS解析查找流程依次为:

浏览器缓存-系统缓存-路由器缓存-ISP DNS缓存-递归搜索

解决方案

DNS预解析是浏览器试图在用户访问链接之前解析域名,这是计算机的正常DNS解析机制。

域名解析后,如果用户确实访问该域名,那么DNS解析时间将不会有延迟。

最明显的例子,DNS预解析在某个页面中包含非常多的域名非常有效,如搜索结果页。

遇到网页中的超链接,DNS prefetching从中提取域名并将其解析为IP地址,这些工作在用户浏览网页时,使用最少的CPU和网络在后台进行解析。

当用户点击这些已经预解析的域名,可以平均减少200毫秒耗时(假设用户最近还未访问过该域名),更重要的是用户不会遇到DNS解析最坏的情况(往往超过1秒)。

DNS Prefetching简介

DNS 请求需要的带宽非常小,但是延迟却有点高,这点在手机网络上特别明显。DNS预解析 能让延迟明显减少一些,例如用户点击链接时。在某些情况下,延迟能减少一秒钟。

在某些浏览器中这个预读取的行为将会与页面实际内容并行发生(而不是串行)。正因如此,某些高延迟的域名的解析过程才不会卡住资源的加载。

这样可以极大的加速(尤其是移动网络环境下)页面的加载。在某些图片较多的页面中,在发起图片加载请求之前预先把域名解析好将会有至少 5% 的图片加载速度提升。

使用

X-DNS-Prefetch-Control 头控制着浏览器的DNS预解析功能

X-DNS_prefetch-Control: on|off

on:启用DNS预解析。在浏览器支持DNS预解析的特性时及时不适用该标签浏览器依然会进行预解析。

off:关闭DNS预解析。这个属性在页面上的链接并不是由你控制的或是你根本不想向这些域名引导数据时非常有用。

浏览器支持

链接:http://caniuse.com/#feat=link-rel-dns-prefetch

示例

打开和关闭DNS预读取

你可以通过在服务器端发送 X-DNS-Prefetch-Control 报头,或是在文档中使用值为 http-equiv 的标签:

<meta http-equiv="x-dns-prefetch-control" content="off">

1

<meta http-equiv="x-dns-prefetch-control" content="off">

强制查询特定主机名

你可以通过使用 rel 属性值为 link type 中的 dns-prefetch 的 标签来对特定域名进行预读取:

<link rel="dns-prefetch" href="http://www.xuanfengge.com/">

1

<link rel="dns-prefetch" href="http://www.xuanfengge.com/">

在这个例子中,Firefox将预解析域名”www.xuanfengge.com”。

特性

Chrome会记住最近使用的10个domain,并且在开启浏览器时自动解析,因此在打开这些常用页面的时候,并不会有DNS Lookup的延迟情况。

chrome使用8个线程专门做DNS Prefetching,而且chrome本身不做dns记录的cache,是直接从操作系统读dns。所以直接修改系统的dns记录或者host是可以直接影响chrome。

浏览器会对a标签的href自动启用DNS Prefetching,所以a标签里包含的域名不需要在head中手动设置link。但是在HTTPS下面不起作用,需要meta来强制开启功能。这个限制的原因是防止窃听者根据DNS Prefetching推断显示在HTTPS页面中超链接的主机名。

DNS解析的包很小,一个UDP的包小于100 bytes,却平均可节省200ms。

本地缓存DNS数量有限,可暂存50-200个domain,Chrome会决定该删除哪些domain的缓存,常用的网站会被标记为“最近使用”,不会那么快被删除。而如google.com、yahoo.com等大型网站过期时间大概在5分钟左右,可以更好的适应服务变化。

场景

页面中的静态资源在不同的domain下,如CSS、JS、图片等文件

适合在以下场景中使用:

  • 电商网站的商品页大量载入不同domain下的商品图,如淘宝
  • 手机网页
  • 大型网站
  • js或服务端重定向

指令

  • chrome://histograms/DNS.PrefetchQueue:查看队列状态
  • chrome://histograms/DNS:查看从浏览器启动到上一页的DNS记录
  • chrome://dns:查看个域名DNS统计
  • chrome://net-internals/#dns:清除host缓存

实验

1. HTTPS页面DNS prefetching

下面的例子,该页面只会预解析b.com,而不会预解析a.com、c.com、d.com。

因为HTTPS需要手动开启才会生效,而且如果明确设置不采用DNS 预解析功能,则会忽略进一步尝试开启。

<a href="http://a.com"> A) Default HTTPS: No prefetching </a> <meta http-equiv="x-dns-prefetch-control" content="on"> <a href="http://b.com"> B) Manual opt-in: Prefetch domain resolution. </a> <meta http-equiv="x-dns-prefetch-control" content="off"> <a href="http://c.com"> C) Manual opt-out: Don't prefetch domain resolution </a> <meta http-equiv="x-dns-prefetch-control" content="on"> <a href="http://d.com"> D) Already opted out: Don't prefetch domain resolution. </a>

1234567

<a href="http://a.com"> A) Default HTTPS: No prefetching </a><meta http-equiv="x-dns-prefetch-control" content="on"><a href="http://b.com"> B) Manual opt-in: Prefetch domain resolution. </a><meta http-equiv="x-dns-prefetch-control" content="off"><a href="http://c.com"> C) Manual opt-out: Don't prefetch domain resolution </a><meta http-equiv="x-dns-prefetch-control" content="on"><a href="http://d.com"> D) Already opted out: Don't prefetch domain resolution. </a>

2. DNS prefetching解析记录

打开页面1:http://www.xuanfengge.com/demo/201705/dns/demo.html

<html> <head></head> <body>     <a href="http://a.youzan.com">a</a>     <a href="http://b.youzan.com">b</a>     <a href="http://c.youzan.com">c</a>     <a href="http://d.youzan.com">d</a> </body> </html>

123456789

<html><head></head><body>    <a href="http://a.youzan.com">a</a>    <a href="http://b.youzan.com">b</a>    <a href="http://c.youzan.com">c</a>    <a href="http://d.youzan.com">d</a></body></html>

Chrome打开 chrome://histograms/DNS.PrefetchQueue 看DNS记录

目前一共22个DNS记录,有9个命中缓存

打开页面2:http://www.xuanfengge.com/demo/201705/dns/demo1.html

<html> <head></head> <body>     <a href="http://a.youzan.com">a</a>     <a href="http://b.youzan.com">b</a>     <a href="http://c.youzan.com">c</a>     <a href="http://d.youzan.com">d</a>     <a href="http://a1.youzan.com">a1</a>     <a href="http://b1.youzan.com">b1</a>     <a href="http://c1.youzan.com">c1</a>     <a href="http://d1.youzan.com">d1</a>     <a href="http://a2.youzan.com">a2</a>     <a href="http://b2.youzan.com">b2</a>     <a href="http://c2.youzan.com">c2</a>     <a href="http://d2.youzan.com">d2</a>     <a href="http://a3.youzan.com">a3</a>     <a href="http://b3.youzan.com">b3</a>     <a href="http://c3.youzan.com">c3</a>     <a href="http://d3.youzan.com">d3</a>     <a href="http://a4.youzan.com">a4</a>     <a href="http://b4.youzan.com">b4</a>     <a href="http://c4.youzan.com">c4</a>     <a href="http://d4.youzan.com">d4</a> </body> </html>

12345678910111213141516171819202122232425

<html><head></head><body>    <a href="http://a.youzan.com">a</a>    <a href="http://b.youzan.com">b</a>    <a href="http://c.youzan.com">c</a>    <a href="http://d.youzan.com">d</a>    <a href="http://a1.youzan.com">a1</a>    <a href="http://b1.youzan.com">b1</a>    <a href="http://c1.youzan.com">c1</a>    <a href="http://d1.youzan.com">d1</a>    <a href="http://a2.youzan.com">a2</a>    <a href="http://b2.youzan.com">b2</a>    <a href="http://c2.youzan.com">c2</a>    <a href="http://d2.youzan.com">d2</a>    <a href="http://a3.youzan.com">a3</a>    <a href="http://b3.youzan.com">b3</a>    <a href="http://c3.youzan.com">c3</a>    <a href="http://d3.youzan.com">d3</a>    <a href="http://a4.youzan.com">a4</a>    <a href="http://b4.youzan.com">b4</a>    <a href="http://c4.youzan.com">c4</a>    <a href="http://d4.youzan.com">d4</a></body></html>

新增20次查询,其中新增4次缓存命中,其它为离散分布在各个时间段。

所以Chrome会对a标签的domain进行预解析。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏24K纯开源

Mac OS平台下应用程序安装包制作工具Packages的使用介绍

一、介绍 2017/12/05更新:packages下载地址:http://s.sudre.free.fr/Software/Packages/resour...

69670
来自专栏软件测试经验与教训

看图说话:文件包含(File Inclusion)漏洞示例

作为测试人员,我们常常听到“安全测试”这个词,但鲜有人真正做过安全测试。从我们的职责“保障质量”角度来说,说是一种“失职”也不为过。那么安全测试是什么,究竟怎么...

23810
来自专栏wblearn

我的博客搭建之git的使用

前天我的github博客搭建好啦,并在本地写了一篇文章<a href="https://wblearn.github.io/2016/12/23/one/"ta...

7610
来自专栏云计算教程系列

如何在macOS上安装Python 3并设置本地编程环境

Python是一种多功能编程语言,可用于许多不同的编程项目。1991年首次出版,其名称灵感来自英国喜剧组织Monty Python,开发团队希望使Python成...

42820
来自专栏北京马哥教育

Python 官方推荐的一款打包工具

原文链接:https://robots.thoughtbot.com/how-to-manage-your-python-projects-with-pipen...

37750
来自专栏北京马哥教育

Linux 线程浅析

关于linux线程 在许多经典的操作系统教科书中, 总是把进程定义为程序的执行实例, 它并不执行什么, 只是维护应用程序所需的各种资源. 而线程则是真正的执行实...

56570
来自专栏云计算教程系列

如何在Debian 8上添加和删除用户

您应该知道如何在新的Linux服务器上执行的最基本任务之一是添加和删除用户。创建新系统时,默认情况下通常只会为您提供root帐户。虽然以root用户身份运行会为...

99830
来自专栏IT派

Python 官方推荐的一款打包工具

在thoughtbot,我们用Ruby和Rails工作,但通常我们总是尝试使用最合适的语言或者框架来解决问题。我最近一直在探索机器学习技术,所以Python使用...

12640
来自专栏技术墨客

React由0到1

    本文记录了本人以及目前团队从无到有使用React的过程,我们将从webpack开始说起,一步一步展现React最基本的开发生态。在这里并不会介绍任何js...

11730
来自专栏黑白安全

8种DOS命令

  它是用来检查网络是否通畅或者网络连接速度的命令。作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它所利用的原理是这样的:...

23420

扫码关注云+社区

领取腾讯云代金券