Linux性能优化——DNS解析

Posted vector6_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux性能优化——DNS解析相关的知识,希望对你有一定的参考价值。

Linux性能优化——DNS解析

在TCP/IP不同协议层我们所关注的网络性能指标不同,在应用层,我们关注的是应用程序的并发连接数、每秒请求数、处理延迟、错误数等,可以使用 wrk、JMeter 等工具,模拟用户的负载,得到想要的测试结果。而在传输层,我们关注的是 TCP、UDP 等传输层协议的工作状况,比如 TCP 连接数、TCP 重传、TCP 错误数等。此时可以使用 iperf、netperf 等,来测试 TCP 或 UDP 的性能。再向下到网络层,我们关注的则是网络包的处理能力,即 PPS。Linux 内核自带的pktgen可以测试这个指标。

本文将对应用层的重要模块DNS解析服务的相关问题及优化方法进行分析。

查询DNS解析配置

我们知道,域名以分层的结构进行管理,相对应的,域名解析其实也是用递归的方式从顶级开始发送给各个层级的域名服务器,直到得到解析结果。当然我们需要做的只是预先配置一个可用的DNS服务器。

通常每级DNS服务器,都会有最近解析记录的缓存。只有在缓存过期或者不存在时,才需要用刚刚提到的递归方式查询。

我们可以通过/etc/resolv.conf 查询系统配置

$ cat /etc/resolv.conf
nameserver 127.0.0.53

另外,DNS 服务通过资源记录的方式,来管理所有数据,它支持 A、CNAME、MX、NS、PTR 等多种类型的记录。比如:

A 记录,用来把域名转换成 IP 地址;CNAME 记录,用来创建别名;NS 记录,则表示该域名对应的域名服务器地址。

简单来说,当我们访问某个网址时,就需要通过 DNS 的 A 记录,查询该域名对应的 IP 地址,然后再通过该 IP 来访问 Web 服务。

我们可以使用 nslookup 命令来查询某个域名的A记录。

root@cfs:/home/cfs# nslookup 163.com
#域名服务器及端口信息
Server:		127.0.0.53
Address:	127.0.0.53#53

#非权威查询结果,由于不是直接管理目标域名的域名服务器
Non-authoritative answer:
Name:	163.com
Address: 123.58.180.8
Name:	163.com
Address: 123.58.180.7

除了 nslookup,另外一个常用的 DNS 解析工具 dig ,就提供了 trace 功能,可以展示递归查询的整个过程。比如可以使用 +trace 表示开启跟踪查询

有时候我们也希望能对局域网内部的主机进行域名解析(即内网域名,大多数情况下为主机名)。Linux 也支持这种行为。可以把主机名和 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解析失败问题

如果我们事先删除了/etc/resolv.conf ,再查询之前域名的地址,

/# nslookup 163.com
;; connection timed out; no servers could be reached

nslookup 会失败并出现 connection timed out; no servers could be reached 的错误。

这种情况下我们ping目的地址也是连通的,其实可以使用 nslookup -debug 开启调试输出,查看查询过程中的详

细步骤,排查其中是否有异常,可以查到,nslookup没有去连接 之前配置的域名服务器。

当然此时在 /etc/resolv.conf 文件中,配置上 DNS 服务器就可以了

DNS解析不稳定问题

通常我们可以使用 time nslookup domain 来输出解析所用的时间。

root@cfs:/home/cfs# time nslookup 163.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	163.com
Address: 123.58.180.7
Name:	163.com
Address: 123.58.180.8


real	0m10.157s
user	0m0.008s
sys	0m0.000s

可以看到,这次解析非常慢,居然用了 10 秒。如果多次运行上面的命令,还可能出现超时失败的情况。

root@cfs:/home/cfs# time nslookup 163.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	163.com
Address: 123.58.180.8
Name:	163.com
Address: 123.58.180.7
;; connection timed out; no servers could be reached


real	0m15.011s
user	0m0.000s
sys	0m0.009s

由此可得,DNS解析的流程不稳定。由于DNS其实也是客户端与服务器交互的过程,且使用了UDP协议,这其中的原因可能有:

  • DNS服务器本身有问题,响应慢并且不稳定;
  • 客户端到DNS服务器的网络延迟比较大;
  • DNS请求或者响应包,在传输过程中丢失。

一般来说我们使用的DNS服务器出问题的概率较小,而延时问题我们可以通过ping来测试,同样丢包的情况也可以通过简单的Ping 来测试。

解决方法是在延迟比较高的情况下,我们可以换一个延迟更小的DNS服务器,或者使用DNS缓存。

不过要注意,我们使用的主流 Linux 发行版,除了最新版本的 Ubuntu (如 18.04 或者更新版本)外,其他版本并没有自动配置 DNS 缓存。

所以,想要为系统开启 DNS 缓存,就需要你做额外的配置。比如,最简单的方法,就是使用 dnsmasq。

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

可以通过 /etc/init.d/dnsmasq start 启动dnsmasq ,然后,修改 /etc/resolv.conf,将 DNS 服务器改为dnsmasq 的监听地址,就将该服务设为了DNS服务器。

小结:

在应用程序的开发过程中,我们必须考虑到 DNS 解析可能带来的性能问题,主要的优化方法有:

对 DNS 解析的结果进行缓存。缓存是最有效的方法,但要注意,一旦缓存过期,还是要去 DNS 服务器重新获取新记录。不过,这对大部分应用程序来说都是可接受的。

对 DNS 解析的结果进行预取。这是浏览器等 Web 应用中最常用的方法,也就是说,不等用户点击页面上的超链接,浏览器就会在后台自动解析域名,并把结果缓存起来。

使用 HTTPDNS 取代常规的 DNS 解析。这是很多移动应用会选择的方法,特别是如今域名劫持普遍存在,使用 HTTP 协议绕过链路中的 DNS 服务器,就可以避免域名劫持的问题。

以上是关于Linux性能优化——DNS解析的主要内容,如果未能解决你的问题,请参考以下文章

前端性能优化总结

Mysql性能优化:从逻辑分层存储引擎到解析过程

前端性能优化之-dns预解析

web性能优化DNS解析与ip

前端性能优化之你该在网络方面做什么?

前端总结--性能优化