[转帖]《Linux性能优化实战》笔记(十九)—— DNS 解析原理与故障案例分析

linux,性能,优化,实战,笔记,十九,dns,解析,原理,故障,案例,分析 · 浏览次数 : 0

小编点评

**1. 使用 DNS 缓存继续优化 1s 的 DNS 解析时间** **步骤:** - 安装 DNS 缓存服务,例如 dnsmasq。 - 修改 /etc/resolv.conf,将 DNS 服务器改为 dnsmasq 的监听地址。 -重新执行多次 nslookup 命令,例如: echo nameserver 127.0.0.1 > /etc/resolv.conftime nslookup time.geekbang.org#输出Server: 127.0.0.1Address: 127.0.0.1#53 Non-authoritative answer:Name: time.geekbang.orgAddress: 39.106.233.176 real 0m0.492suser 0m0.007ssys 0m0.006s time nslookup time.geekbang.org#输出Server: 127.0.0.1Address: 127.0.0.1#53 Non-authoritative answer:Name: time.geekbang.orgAddress: 39.106.233.176 real 0m0.011suser 0m0.008ssys 0m0.003s **2. 优化 DNS 解析时间** - 使用 dnsmasq 等工具,设置 DNS 服务器的缓存时间。 - 降低 DNS 解析服务器的缓存时间。 - 使用 DNS 解析工具,例如 nslookup,设置缓存时间。 **3. 监控 DNS 解析时间** - 使用工具,例如 nslookup,监控 DNS 解析时间。 - 跟踪 DNS 解析时间变化,如果发现出现异常,则进行分析。 **4. 调整 DNS 解析时间** - 根据实际情况,调整 DNS 解析时间。 - 例如,如果需要加速 DNS 解析,可以降低缓存时间。 **5. 总结** 使用 DNS 缓存服务可以优化 DNS 解析时间,降低解析时间。同时,通过优化 DNS 解析时间,可以提高应用程序的性能。

正文

一、 域名与 DNS 解析

域名主要是为了方便让人记住,而 IP 地址是机器间的通信的真正机制。以 time.geekbang.org 为例,最后面的 org 是顶级域名,中间的 geekbang 是二级域名,而最左边的 time 则是三级域名。点(.)是所有域名的根,所有域名都以点作为后缀。

把域名转换为 IP 地址的服务,就是域名解析服务(DNS)。对应的服务器就是域名服务器,网络协议则是 DNS 协议。DNS 协议在 TCP/IP 栈中属于应用层,不过实际传输还是基于 UDP 或者 TCP协议(UDP 居多) ,并且域名服务器一般监听在端口 53 上。

既然域名以分层的结构进行管理,相对应的,域名解析也是用递归的方式,发送给每个层级的域名服务器,直到得到解析结果。通常来说,每级 DNS 服务器都会有最近解析记录的缓存。当缓存命中时,直接用缓存中的记录应答;如果缓存过期或者不存在,才需要用刚刚提到的递归方式查询。

所以,系统管理员在配置 Linux 系统的网络时,除了需要配置 IP 地址,还需要配置DNS 服务器,这样才可以通过域名来访问外部服务。可以执行下面的命令来查询你的DNS配置

  1. $ cat /etc/resolv.conf
  2. nameserver 114.114.114.114

另外,DNS 服务通过资源记录的方式,来管理所有数据,它支持 A、CNAME、MX、NS、PTR 等多种类型的记录。比如
A 记录,用来把域名转换成 IP 地址;CNAME 记录,用来创建别名; NS 记录,则表示该域名对应的域名服务器地址。

比如以 time.geekbang.org 为例,执行下面的 nslookup 命令,就可以查询到这个域名的 A 记录,可以看到,它的 IP 地址是 39.106.233.176:

  1. $ nslookup time.geekbang.org
  2. # 域名服务器及端口信息
  3. Server: 114.114.114.114
  4. Address: 114.114.114.114#53
  5. # 非权威查询结果
  6. Non-authoritative answer:
  7. Name: time.geekbang.org
  8. Address: 39.106.233.17

这里要注意,由于 114.114.114.114 并不是直接管理 time.geekbang.org 的域名服务器,所以查询结果是非权威的。使用上面的命令,你只能得到 114.114.114.114 查询的结果。

 

前面还提到,如果没有命中缓存,DNS 查询实际上是一个递归过程,那有没有方法可以知道整个递归查询的执行呢?其实除了 nslookup,另外一个常用的 DNS 解析工具 dig ,就提供了 trace 功能,可以展示递归查询的整个过程。

  1. # +trace表示开启跟踪查询
  2. # +nodnssec表示禁止DNS安全扩展
  3. $ dig +trace +nodnssec time.geekbang.org
  4. ; <<>> DiG 9.11.3-1ubuntu1.3-Ubuntu <<>> +trace +nodnssec time.geekbang.org
  5. ;; global options: +cmd
  6. . 322086 IN NS m.root-servers.net.
  7. . 322086 IN NS a.root-servers.net.
  8. . 322086 IN NS i.root-servers.net.
  9. . 322086 IN NS d.root-servers.net.
  10. . 322086 IN NS g.root-servers.net.
  11. . 322086 IN NS l.root-servers.net.
  12. . 322086 IN NS c.root-servers.net.
  13. . 322086 IN NS b.root-servers.net.
  14. . 322086 IN NS h.root-servers.net.
  15. . 322086 IN NS e.root-servers.net.
  16. . 322086 IN NS k.root-servers.net.
  17. . 322086 IN NS j.root-servers.net.
  18. . 322086 IN NS f.root-servers.net.
  19. ;; Received 239 bytes from 114.114.114.114#53(114.114.114.114) in 1340 ms
  20. org. 172800 IN NS a0.org.afilias-nst.info.
  21. org. 172800 IN NS a2.org.afilias-nst.info.
  22. org. 172800 IN NS b0.org.afilias-nst.org.
  23. org. 172800 IN NS b2.org.afilias-nst.org.
  24. org. 172800 IN NS c0.org.afilias-nst.info.
  25. org. 172800 IN NS d0.org.afilias-nst.org.
  26. ;; Received 448 bytes from 198.97.190.53#53(h.root-servers.net) in 708 ms
  27. geekbang.org. 86400 IN NS dns9.hichina.com.
  28. geekbang.org. 86400 IN NS dns10.hichina.com.
  29. ;; Received 96 bytes from 199.19.54.1#53(b0.org.afilias-nst.org) in 1833 ms
  30. time.geekbang.org. 600 IN A 39.106.233.176
  31. ;; Received 62 bytes from 140.205.41.16#53(dns10.hichina.com) in 4 ms
  • 第一部分,是从 114.114.114.114 查到的一些根域名服务器(.)的 NS 记录。
  • 第二部分,是从 NS 记录结果中选一个(h.root-servers.net),并查询顶级域名 org.的 NS 记录。
  • 第三部分,是从 org. 的 NS 记录中选择一个(b0.org.afilias-nst.org),并查询二级域名 geekbang.org. 的 NS 服务器。
  • 最后一部分,就是从 geekbang.org. 的 NS 服务器(dns10.hichina.com)查询最终主机 time.geekbang.org. 的 A 记录。

这个输出里展示的各级域名的 NS 记录,其实就是各级域名服务器的地址,可以让你更清楚DNS 解析的过程。 

很多时候,我们也希望能对局域网内部的主机进行域名解析,可以把主机名和 IP 地址的映射关系,写入本机的 /etc/hosts 文件中。这样,指定的主机名就可以在本地直接找到目标 IP。

  1. $ cat /etc/hosts
  2. 127.0.0.1 localhost localhost.localdomain
  3. ::1 localhost6 localhost6.localdomain6
  4. 192.168.0.100 domain.com

或者,你还可以在内网中,搭建自定义的 DNS 服务器,专门用来解析内网中的域名。而内网 DNS 服务器,一般还会设置一个或多个上游 DNS 服务器,用来解析外网的域名。

清楚域名与 DNS 解析的基本原理后,接下来,我就带你一起来看几个案例,实战分析DNS 解析出现问题时,该如何定位。
 

二、 案例分析

案例 1:DNS 解析失败

例如执行 nslookup time.geekbang.org 报错

  1. nslookup time.geekbang.org
  2. #报错如下
  3. ;; connection timed out; no servers could be reached

这个命令阻塞很久后,还是失败了,报了 connection timed out 和 no servers could be reached 错误。看到这里,估计你的第一反应就是网络不通了,到底是不是这样呢?我们用 ping 工具检查试试。

  1. ping -c3 114.114.114.114
  2. PING 114.114.114.114 (114.114.114.114): 56 data bytes
  3. 64 bytes from 114.114.114.114: icmp_seq=0 ttl=56 time=31.116 ms
  4. 64 bytes from 114.114.114.114: icmp_seq=1 ttl=60 time=31.245 ms
  5. 64 bytes from 114.114.114.114: icmp_seq=2 ttl=68 time=31.128 ms
  6. --- 114.114.114.114 ping statistics ---
  7. 3 packets transmitted, 3 packets received, 0% packet loss
  8. round-trip min/avg/max/stddev = 31.116/31.163/31.245/0.058 ms

这个输出中,你可以看到网络是通的。

要怎么知道 nslookup 命令失败的原因呢?这里其实有很多方法,最简单的一种,就是开启 nslookup 的调试输出,查看查询过程中的详细步骤,排查其中是否有异常。

  1. nslookup -debug time.geekbang.org
  2. #输出
  3. ;; Connection to 127.0.0.1 #53(127.0.0.1) for time.geekbang.org failed: connection refused.
  4. ;; Connection to ::1 #53(::1) for time.geekbang.org failed: address not available.

可以看到,nslookup 连接环回地址(127.0.0.1 和 ::1)的 53 端口失败。这里就有问题了,为什么会去连接环回地址?

你可能已经想到了症结所在——可能是因为没有配置 DNS 服务器。那我们就执行下面的命令确认一下:

cat /etc/resolv.conf

果然,这个命令没有任何输出,说明的确没有配置 DNS 服务器。

到这一步,很自然的,我们就知道了解决方法。在 /etc/resolv.conf 文件中,配置上 DNS 服务器就可以了。配置好后,重新执行 nslookup 命令。自然,我们现在发现,这次可以正常解析了:

  1. echo "nameserver 114.114.114.114" > /etc/resolv.conf
  2. nslookup time.geekbang.org
  3. #输出
  4. Server: 114.114.114.114
  5. Address: 114.114.114.114#53
  6. Non-authoritative answer:
  7. Name: time.geekbang.org
  8. Address: 39.106.233.176

 

案例 2:DNS 解析不稳定

还是运行 nslookup 命令,解析 time.geekbang.org 的 IP 地址。不过,这次要加一个 time 命令,输出解析所用时间。

  1. time nslookup time.geekbang.org
  2. #输出
  3. Server: 8.8.8.8
  4. Address: 8.8.8.8#53
  5. Non-authoritative answer:
  6. Name: time.geekbang.org
  7. Address: 39.106.233.176
  8. real 0m10.349s
  9. user 0m0.004s
  10. sys 0m0.0

可以看到,这次解析非常慢,居然用了 10 秒。如果多次运行上面的 nslookup 命令,可能偶尔还会碰到下面这种错误:

  1. time nslookup time.geekbang.org
  2. #输出
  3. ;; connection timed out; no servers could be reached
  4. real 0m15.011s
  5. user 0m0.006s
  6. sys 0m0.006s

换句话说,跟上一个案例类似,也会出现解析失败的情况。综合来看,现在 DNS 解析的结果不但比较慢,而且还会发生超时失败的情况。这是为什么呢?碰到这种问题该怎么处理呢?

其实,根据前面的讲解,我们知道,DNS 解析,说白了就是客户端与服务器交互的过程,并且这个过程还使用了 UDP 协议。那么,对于整个流程来说,解析结果不稳定,就有很多种可能的情况了。比方说:

  • DNS 服务器本身有问题,响应慢并且不稳定;
  • 客户端到 DNS 服务器的网络延迟比较大;
  • DNS 请求或者响应包,在某些情况下被链路中的网络设备弄丢了

根据上面 nslookup 的输出,可以看到,现在客户端连接的 DNS 是 8.8.8.8,这是Google 提供的 DNS 服务,出问题的概率
应该比较小。基本排除了第一个可能。那是不是本机到 DNS 服务器的延迟比较大呢?

可以用ping 来测试服务器的延迟。比如,你可以运行下面的命令:

  1. ping -c3 8.8.8.8
  2. #输出
  3. PING 8.8.8.8 (8.8.8.8): 56 data bytes
  4. 64 bytes from 8.8.8.8: icmp_seq=0 ttl=31 time=137.637 ms
  5. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=31 time=144.743 ms
  6. 64 bytes from 8.8.8.8: icmp_seq=2 ttl=31 time=138.576 ms
  7. --- 8.8.8.8 ping statistics ---
  8. 3 packets transmitted, 3 packets received, 0% packet loss
  9. round-trip min/avg/max/stddev = 137.637/140.319/144.743/3.152 ms

从 ping 的输出可以看到,延迟已经达到了 140ms,这也就可以解释,为什么解析这么慢了。实际上,如果你多次运行上面的 ping 测试,还会看到偶尔出现的丢包现象。

  1. ping -c3 8.8.8.8
  2. #输出
  3. PING 8.8.8.8 (8.8.8.8): 56 data bytes
  4. 64 bytes from 8.8.8.8: icmp_seq=0 ttl=30 time=134.032 ms
  5. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=30 time=431.458 ms
  6. --- 8.8.8.8 ping statistics ---
  7. 3 packets transmitted, 2 packets received, 33% packet loss
  8. round-trip min/avg/max/stddev = 134.032/282.745/431.458/148.713 ms

这也进一步解释了,为什么 nslookup 偶尔会失败,正是网络链路中的丢包导致的。碰到这种问题该怎么办呢?显然,既然延迟太大,那就换一个延迟更小的 DNS 服务器,比如电信提供的 114.114.114.114。

配置之前,我们可以先用 ping 测试看看,它的延迟是不是真的比 8.8.8.8 好。可以看到,它的延迟只有 31ms:

  1. ping -c3 114.114.114.114
  2. #输出
  3. PING 114.114.114.114 (114.114.114.114): 56 data bytes
  4. 64 bytes from 114.114.114.114: icmp_seq=0 ttl=67 time=31.130 ms
  5. 64 bytes from 114.114.114.114: icmp_seq=1 ttl=56 time=31.302 ms
  6. 64 bytes from 114.114.114.114: icmp_seq=2 ttl=56 time=31.250 ms
  7. --- 114.114.114.114 ping statistics ---
  8. 3 packets transmitted, 3 packets received, 0% packet loss
  9. round-trip min/avg/max/stddev = 31.130/31.227/31.302/0.072 ms

这个结果表明,延迟的确小了很多。我们继续执行下面的命令,更换 DNS 服务器,然后,再次执行 nslookup 解析命令:

  1. echo nameserver 114.114.114.114 > /etc/resolv.conf
  2. time nslookup time.geekbang.org
  3. #输出
  4. Server: 114.114.114.114
  5. Address: 114.114.114.114#53
  6. Non-authoritative answer:
  7. Name: time.geekbang.org
  8. Address: 39.106.233.176
  9. real 0m0.064s
  10. user 0m0.007s
  11. sys 0m0.006s

你可以发现,现在只需要 64ms 就可以完成解析,比刚才的 10s 要好很多。到这里,问题看似就解决了。不过,如果你多次运行 nslookup 命令,估计就不是每次都有好结果了。比如,在我的机器中,就经常需要 1s 甚至更多的时间。

  1. time nslookup time.geekbang.org
  2. #输出
  3. Server: 114.114.114.114
  4. Address: 114.114.114.114#53
  5. Non-authoritative answer:
  6. Name: time.geekbang.org
  7. Address: 39.106.233.176
  8. real 0m1.045s
  9. user 0m0.007s
  10. sys 0m0.004s

 

案例 3:利用 DNS 缓存继续优化

1s 的 DNS 解析时间还是太长了,对很多应用来说也是不可接受的。该怎么解决这个问题呢?我想你一定已经想到了,那就是使用 DNS 缓存。这样,只有第一次查询时需要去 DNS 服务器请求,以后的查询,只要 DNS 记录不过期,使用缓存中的记录就可以了。

不过要注意,除了最新版本的 Ubuntu(18.04及以上)外,其他版本并没有自动配置 DNS 缓存。所以,想要为系统开启 DNS 缓存,就需要你做额外的配置。比如,最简单的方法,就是使用 dnsmasq。

dnsmasq 是最常用的 DNS 缓存服务之一,还经常作为 DHCP 服务来使用。它的安装和配置都比较简单,性能也可以满足绝大多数应用程序对 DNS 缓存的需求。执行下面的命令,就可以启动 dnsmasq:

  1. /etc/init.d/dnsmasq start
  2. #输出
  3. * Starting DNS forwarder and DHCP server dnsmasq [ OK ]

然后,修改 /etc/resolv.conf,将 DNS 服务器改为 dnsmasq 的监听地址,这儿是127.0.0.1。接着,重新执行多次 nslookup 命令:

  1. echo nameserver 127.0.0.1 > /etc/resolv.conf
  2. time nslookup time.geekbang.org
  3. #输出
  4. Server: 127.0.0.1
  5. Address: 127.0.0.1#53
  6. Non-authoritative answer:
  7. Name: time.geekbang.org
  8. Address: 39.106.233.176
  9. real 0m0.492s
  10. user 0m0.007s
  11. sys 0m0.006s
  12. time nslookup time.geekbang.org
  13. #输出
  14. Server: 127.0.0.1
  15. Address: 127.0.0.1#53
  16. Non-authoritative answer:
  17. Name: time.geekbang.org
  18. Address: 39.106.233.176
  19. real 0m0.011s
  20. user 0m0.008s
  21. sys 0m0.003s

可以看到,只有第一次的解析很慢,需要 0.5s,以后的每次解析都很快,只需要11ms,并且后面每次 DNS 解析需要的时间也都很稳定。

文章知识点与官方知识档案匹配,可进一步学习相关知识
CS入门技能树Linux入门初识Linux32624 人正在系统学习中

与[转帖]《Linux性能优化实战》笔记(十九)—— DNS 解析原理与故障案例分析相似的内容:

[转帖]《Linux性能优化实战》笔记(十九)—— DNS 解析原理与故障案例分析

一、 域名与 DNS 解析 域名主要是为了方便让人记住,而 IP 地址是机器间的通信的真正机制。以 time.geekbang.org 为例,最后面的 org 是顶级域名,中间的 geekbang 是二级域名,而最左边的 time 则是三级域名。点(.)是所有域名的根,所有域名都以点作为后缀。 把域

[转帖]《Linux性能优化实战》笔记(十七)—— Linux网络基础与性能指标

一、 网络模型 1. OSI 网络模型(七层) 为了解决网络互联中异构设备的兼容性问题,并解耦复杂的网络包处理流程,OSI 模型把网络互联的框架分为七层,每个层负责不同的功能。其中, 应用层,负责为应用程序提供统一的接口。表示层,负责把数据转换成兼容接收系统的格式。会话层,负责维护计算机之间的通信连

[转帖]《Linux性能优化实战》笔记(十五)—— 磁盘IO的工作原理

前一篇介绍了文件系统的工作原理,这一篇来看看磁盘IO的工作原理 一、 磁盘 1. 按存储介质分类 磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘。 机械磁盘,也称为硬盘驱动器(Hard Disk Driver,HDD),主要由盘片和读写磁头组成,数据存储在盘

[转帖]《Linux性能优化实战》笔记(一)—— 平均负载

最近在看极客时间的《Linux性能优化实战》课程,记录下学习内容。 一、 平均负载(Load Average) 1. 概念 我们都知道uptime命令的最后三列分别是过去 1 分钟、5 分钟、15 分钟系统的平均负载,到底平均负载是什么? 简单来说,平均负载是指单位时间内,系统处于可运行状态和不可中

[转帖]《Linux性能优化实战》笔记(二)—— CPU 上下文切换(上)

上一篇的最后一个例子,在多个进程竞争CPU时,我们看到每个进程实际上%usr部分只有20%多,70%多是在wait,但是load远远高于单个进程使用CPU达到100%。 这让我想到之前看的RWP公开课,里面有一篇连接池管理。为什么相同的业务量,起6千个连接(进程)远远要慢于200个连接,因为绝大多数

[转帖]《Linux性能优化实战》笔记(八)—— 内存是怎么工作的

一、 内存映射 我们通常所说的内存容量,指的是物理内存。物理内存也称为主存,大多数计算机用的主存都是动态随机访问内存(DRAM)。只有内核才可以直接访问物理内存。那么,进程要访问内存时,该怎么办呢? Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以

[转帖]《Linux性能优化实战》笔记(22)—— 网络丢包问题分析

所谓丢包,是指在网络数据的收发过程中,由于种种原因,数据包还没传输到应用程序中,就被丢弃了。这些被丢弃包的数量,除以总的传输包数,也就是我们常说的丢包率。丢包率是网络性能中最核心的指标之一。丢包通常会带来严重的性能下降,特别是对 TCP 来说,丢包通常意味着网络拥塞和重传,进而还会导致网络延迟增大、

[转帖]《Linux性能优化实战》笔记(23)—— 内核线程 CPU 利用率过高,perf 与 火焰图

在排查网络问题时,我们还经常碰到的一个问题,就是内核线程的 CPU 使用率很高。比如,在高并发的场景中,内核线程 ksoftirqd 的 CPU 使用率通常就会比较高。回顾一下前面学过的 CPU 和网络模块,你应该知道,这是网络收发的软中断导致的。 要分析 ksoftirqd 这类 CPU 使用率比

[转帖]《Linux性能优化实战》笔记(24)—— 动态追踪 DTrace

使用 perf 对系统内核线程进行分析时,内核线程依然还在正常运行中,所以这种方法也被称为动态追踪技术。动态追踪技术通过探针机制来采集内核或者应用程序的运行信息,从而可以不用修改内核和应用程序的代码就获得丰富的信息,帮你分析、定位想要排查的问题。 以往,在排查和调试性能问题时,我们往往需要先为应用程

[转帖]《Linux性能优化实战》笔记(25)—— 总结:Linux 性能工具速查

一、 性能工具速查 在梳理性能工具之前,首先给你提一个问题,那就是,在什么情况下,我们才需要去查找、挑选性能工具呢? 其实在我看来,只有当你想了解某个性能指标,却不知道该怎么办的时候,才会想到,“要是有一个性能工具速查表就好了”这个问题。如果已知一个性能工具可用,我们更多会去查看这个工具的手册,找出