目录

域名和DNS解析

案例分析

DNS解析失败

DNS解析不稳定

优化总结


IP地址是TCP/IP协议中,用来确定通讯双方的一个重要标识,每个IP地址又包括了主机号和网络号两部分,相同网络号的主机组成一个子网,不同子网再通过路由连接,组成一个庞大的网络
但IP地址不方便记忆,于是又了NDS(Domain Name System)域名系统,是互联网中最基础的一项服务,主要提供域名和IP地址之间映射关系的查询服务

DNS不仅方便人们访问不同的互联网服务,更提供了动态服务发现,全局负载均衡(Global Server Load Balance GSLB)的机制吗,这样DNS就可以选择离用户最近的IP来提供服务,即使后端服务的IP地址发生变化,用户依然可以用相同的域名来访问

域名和DNS解析

域名是全球唯一的,需要通过专门的域名注册商才可以申请注册,为了组织全球互联网中众多的计算机,域名同样用点来分开,形成一个分层的结构,而每个被点分割开的字符串,就构成了域名中的一个层级,并且为之越靠后,层级越高
以极客时间 time.geekbang.org 为列
这个字符串中,最后面的org是顶级域名
中间的geekbang是二级域名
最左边的time是三级域名

如下图所示,注意 .  是所有域名的根,也就是说所有域名都以点作为后缀,可以理解为在域名解析过程中,所有域名都以点结束

通过理解这几个概念,可以看出,域名是为了方便人记住,而IP地址是机器间通讯的真正机制,把域名转换为IP地址的服务,也就是开头提到的域名解析服务NDS,对应的服务器就是域名服务器,网络协议为DNS
注意,DNS在TCP/IP中属于应用层,不过实际传输还是基于UDP或TCP协议(UDP居多),并且域名服务器一般在端口53上监听

域名解析也是用递归的方式,从顶层开始,以此类推,发送给每个层级的域名服务器,直到得到解析结果
递归查询过程中,不需要用户操作,DNS服务器会替用户完成
通常来说,每层的NDS服务器,都会有最近解析记录的缓存,当缓冲命中时,直接用缓存中的记录应答就可以了,如果缓存过期或者不存在,才需要用递归的方式查询

系统管理员在配置Linux系统网络时,除了需要配置IP地址,还需要给它配置DNS服务器,这样它才可以通过欲望来访问外部服务
如配置114.114.114.114这个域名服务器

cat /etc/resolv.conf
nameserver 114.114.114.114

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

当访问某个网址时,就需要通过DNS的A记录,查询该域名对应的IP地址,然后再通过IP来访问Web服务
比如,访问极客时间 time.geekbang.org,执行nslookup命令,可以查询到这个域名的A记录,可以看到它的IP地址信息

nslookup time.geekbang.org
Server:         114.114.114.114
Address:        114.114.114.114#53Non-authoritative answer:
Name:   time.geekbang.org
Address: 39.106.233.176

通过debug方式执行nslookup的结果

nslookup -debug time.geekbang.org
Server:         114.114.114.114
Address:        114.114.114.114#53------------QUESTIONS:time.geekbang.org, type = A, class = INANSWERS:->  time.geekbang.orginternet address = 39.106.233.176ttl = 324AUTHORITY RECORDS:ADDITIONAL RECORDS:
------------
Non-authoritative answer:
Name:   time.geekbang.org
Address: 39.106.233.176

如果想知道整个查询过程,可以用另外一个DNS查询工具dig

# +trace表示开启跟踪查询
# +nodnssec 表示禁止DNS安全扩展
dig +trace +nodnssec time.geekbang.org; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> +trace +nodnssec time.geekbang.org
;; global options: +cmd
.                       357157  IN      NS      i.root-servers.net.
.                       357157  IN      NS      c.root-servers.net.
.                       357157  IN      NS      m.root-servers.net.
.                       357157  IN      NS      b.root-servers.net.
.                       357157  IN      NS      a.root-servers.net.
.                       357157  IN      NS      e.root-servers.net.
.                       357157  IN      NS      l.root-servers.net.
.                       357157  IN      NS      j.root-servers.net.
.                       357157  IN      NS      f.root-servers.net.
.                       357157  IN      NS      k.root-servers.net.
.                       357157  IN      NS      g.root-servers.net.
.                       357157  IN      NS      h.root-servers.net.
.                       357157  IN      NS      d.root-servers.net.
;; Received 239 bytes from 114.114.114.114#53(114.114.114.114) in 455 msorg.                    172800  IN      NS      a0.org.afilias-nst.info.
org.                    172800  IN      NS      a2.org.afilias-nst.info.
org.                    172800  IN      NS      b0.org.afilias-nst.org.
org.                    172800  IN      NS      b2.org.afilias-nst.org.
org.                    172800  IN      NS      c0.org.afilias-nst.info.
org.                    172800  IN      NS      d0.org.afilias-nst.org.
;; Received 448 bytes from 192.203.230.10#53(e.root-servers.net) in 361 msgeekbang.org.           86400   IN      NS      dns10.hichina.com.
geekbang.org.           86400   IN      NS      dns9.hichina.com.
;; Received 96 bytes from 199.19.54.1#53(b0.org.afilias-nst.org) in 368 mstime.geekbang.org.      600     IN      A       39.106.233.176
;; Received 62 bytes from 106.11.211.56#53(dns10.hichina.com) in 6 ms

dig trace的输出,主要包括四部分

  • 第一部分,是从114.114.114.114查到的一些根域名服务器 . 的NS记录
  • 第二部分,是从NS记录结果中选一个 h.root-server.net,并查询顶级域名org. 的NS记录
  • 第三部分,是从org. 的NS记录中选一个b0.org.afilias-nst.org,并查询二级域名geekbang.org的NS服务器
  • 第四部分,是从geekbang.org的NS服务器nds10.hichina.com查询最终主机time.geekbang.org的A记录

这个输出里展示的各级域名的NS记录,其实就是各级域名服务器的地址,下面是整个查询的流程图

当然,不仅仅是发布到互联网的服务器需要域名,对局域网内部的主机进行域名解析,即内网域名,大多数情况下为主机名,Linux也支持这种行为
可以把主机名和IP地址的映射关系,写入本机的/etc/hosts文件中,这样指定的主机名就可以在本地直接查找到目标IP,比如

cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

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

案例分析

案例准备
拉取案例中使用的Docker镜像

docker pull feisky/dnsutils
Using default tag: latest
Trying to pull repository docker.io/feisky/dnsutils ...
latest: Pulling from docker.io/feisky/dnsutils
38e2e6cd5626: Already exists
705054bc3f5b: Already exists
c7051e069564: Already exists
7308e914506c: Already exists
9b20820a1a69: Pull complete
8633a2284391: Pull complete
89ab6a8002a6: Pull complete
Digest: sha256:a23534daa60aad8736823219852b6dbd9b51e84ddbaf42e38b54c68954719766
Status: Downloaded newer image for docker.io/feisky/dnsutils:latest

查看当前主机配置的DNS服务器

cat /etc/resolv.conf
options timeout:1 attempts:1 rotate single-request-reopen
search localdomain
nameserver 114.114.114.114

DNS解析失败

首先进入容器环境

# 进入案例的SHELL终端中
docker run -it --rm -v $(mktemp):/etc/resolv.conf feisky/dnsutils bash

接着,在容器中,执行DNS查询命令,还是查询极客时间地址

# root后面的 29e9097050ca 是Docker生成的ID前缀
root@29e9097050ca:/# nslookup time.geekbang.org
;; connection timed out; no servers could be reached

这个命令阻塞了一段时间最后报错,连接超时,服务不可达
检查一下本地到114的连通性

root@29e9097050ca:/# ping -c 3 114.114.114.114
PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: icmp_seq=0 ttl=64 time=32.986 ms
64 bytes from 114.114.114.114: icmp_seq=1 ttl=71 time=32.972 ms
64 bytes from 114.114.114.114: icmp_seq=2 ttl=88 time=33.018 ms
--- 114.114.114.114 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 32.972/32.992/33.018/0.000 ms

网络是通的,但nslookup执行失败了,这时候开启nslookup的调试输出,看查询过程中的详细步骤,排查异常

root@29e9097050ca:/# nslookup -debug time.geekbang.org
;; Connection to 127.0.0.1#53(127.0.0.1) for time.geekbang.org failed: connection refused.
;; Connection to ::1#53(::1) for time.geekbang.org failed: connection refused.

可以看到nslookup连接环回地址127.0.0.1和::1的53端口失败,正常来说应该是连接114.114.114.114的
但这里却连接到本地了,检查下DNS的本地配置文件

#结果是空的
cat /etc/resolv.conf

重新配置上DNS服务器,再执行nslookup命令,这次就正常了

echo "nameserver 114.114.114.114" > /etc/resolv.conf
root@29e9097050ca:/# nslookup time.geekbang.org
Server:         114.114.114.114
Address:        114.114.114.114#53Non-authoritative answer:
Name:   time.geekbang.org
Address: 39.106.233.176

最后在终端中执行exit命令退出容器,Docker会自动清理刚才运行的容器

DNS解析不稳定

再进入第二个案例,使用下面命令

docker run -it --rm --cap-add=NET_ADMIN --dns 8.8.8.8 feisky/dnsutils bash

再用nslookup查询,并加上time,案例中给出的查询时间是10秒,甚至还有超时,但我这里查询很快,可能是DNS
缓存等其他原因导致的

time nslookup time.geekbang.org
Server:         8.8.8.8
Address:        8.8.8.8#53Non-authoritative answer:
Name:   time.geekbang.org
Address: 39.106.233.176real    0m0.245s
user    0m0.006s
sys     0m0.006s

需要245毫秒完成
DNS解析,其实就是客户端与服务器交互的课程,并且这个过程还使用了UDP
对于整个流程,不稳定的情况有很多,比如

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

根据nslookup的输出,客户端连接的DNS是8.8.8.8,也就是谷歌提供的DNS服务器
假设谷歌提供的DNS服务器是正常的
那么测试一下本机到DNS服务器的延迟情况

ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=38 time=53.284 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=38 time=53.193 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=38 time=53.228 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 53.193/53.235/53.284/0.037 ms

ping的延迟是50多毫秒,多执行几次ping,偶尔也有超时丢包的情况
nslookup执行失败,慢就是因为网络链路中的丢包延迟导致的
既然延迟大,就换一个DNS服务器,比如使用电信的114.114.114.114
先测试一下 到114的连通情况

ping -c 3 114.114.114.114
PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: icmp_seq=0 ttl=86 time=32.906 ms
64 bytes from 114.114.114.114: icmp_seq=1 ttl=66 time=32.904 ms
64 bytes from 114.114.114.114: icmp_seq=2 ttl=91 time=34.569 ms
--- 114.114.114.114 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 32.904/33.460/34.569/0.784 ms

根据结果看,稍微好一些,从延迟50毫秒 -> 延迟30毫秒
执行下面命令,更换DNS服务器,再执行nslookup解析命令

cat /etc/resolv.conf
search localdomain
nameserver 8.8.8.8
options timeout:1 attempts:1 rotate single-request-reopenroot@879899eacac7:/# echo "nameserver 114.114.114.114" > /etc/resolv.conf
root@879899eacac7:/# cat /etc/resolv.conf
nameserver 114.114.114.114time nslookup time.geekbang.org
Server:         114.114.114.114
Address:        114.114.114.114#53Non-authoritative answer:
Name:   time.geekbang.org
Address: 39.106.233.176real    0m0.083s
user    0m0.008s
sys     0m0.002s

这次只需要83毫秒就可以完成
不过偶尔还是会有一些时间比较长的,可能当时网络比较繁忙所以返回的结果就比较慢了
其实第一次解析完后,可以将结果放到DNS缓存中
想要为系统开启DNS缓存,就需要额外的配置,最简单的方法是使用 dnsmasq
dnsmasq 是最常用的NDS缓存服务之一,还经常作为DHCP服务来使用,它安装和配置都比较简单,性能也可以满足绝大多数应用程序对DNS缓存的需求
执行下面命令

/etc/init.d/dnsmasq start* Starting DNS forwarder and DHCP server dnsmasq                        [ OK ]

修改resolv.conf文件,将DNS服务器改为dnsmasq的监听地址,这里是127.0.0.1
再多执行几次nslookup

echo "nameserver 127.0.0.1" > /etc/resolv.conftime nslookup time.geekbang.org
Server:         127.0.0.1
Address:        127.0.0.1#53Non-authoritative answer:
Name:   time.geekbang.org
Address: 39.106.233.176real    0m0.012s
user    0m0.007s
sys     0m0.003s

多次解析之后发现只需要10毫秒多一点就可以完成了,而且之后的解析时间也都很稳定
案例最后,可以执行exit 退出容器终端,Docker会自动清理案例容器

优化总结

DNS是互联网中最基础的一项服务,提供了域名和IP地址间映射关系的查询服务,很多应用程序再最初开发时,并没有考虑DNS解析的问题,后续出问题排查很久才发现,是DNS解析慢导致的

常见的DNS优化方法如下

  • 对DNS解析结果进行缓存,缓存是最有效的方法,不过缓存一旦过期还是要去DNS服务器重新获取新记录,但对大部分应用来说都可以接受
  • 对DNS解析的结果进行预取,这是浏览器等Web应用中最常见的方法,不等用户点击页面上的超链接,浏览器会在后台自动解析域名,并把结果缓存起来
  • 使用HTTPNDS代替DNS解析,这是很多移动应用会选择的方式,特别是域名劫持普遍存在,使用HTTP协议绕过链路中的DNS服务器,可以避免域名劫持的问题
  • 基于DNS的全局负载均衡(GSLB),不仅为服务提供了负载均衡和高可用的功能,还可以根据用户的位置,返回距离最近的IP地址

Linux性能优化-DNS解析相关推荐

  1. Linux性能优化——DNS解析

    Linux性能优化--DNS解析 在TCP/IP不同协议层我们所关注的网络性能指标不同,在应用层,我们关注的是应用程序的并发连接数.每秒请求数.处理延迟.错误数等,可以使用 wrk.JMeter 等工 ...

  2. 有关前端性能优化—DNS解析优化的方法?

    DNS简介与域名解析 DNS全称为Domain Name System,即域名系统,是域名和IP地址相互映射的一个分布式数据库. 域名系统DNS将主机名映射到IP地址,就像电话簿将人们的姓名映射到他们 ...

  3. 前端性能优化-DNS解析优化

    1.DNS缓存 DNS查询过程大约消耗20毫秒,在DNS查询过程中,浏览器什么都不会做,保持空白.如果DNS查询很多,网页性能会受到很大影响,因此需要用到DNS缓存.  不同浏览器的缓存机制不同: I ...

  4. Linux 性能优化工具包 sysstat 以及 sysstat 服务(sar 命令解析)

    1. sysstat service 1.1. /etc/cron.d/sysstat Linux 下的性能分析,包括CPU使用情况,内存使用情况,IO状态等等与系统相关的状态,少不了要使用 syss ...

  5. linux性能优化--cpu篇

    linux性能优化--cpu篇 前言 负载 CPU使用率 proc perf 一些链接 `perf list` 比较有用的event `perf stat` `perf record` Profili ...

  6. 【Linux 性能优化系列】Linux 性能优化 -- CPU 性能篇(三) Linux 软中断

    [Linux 性能优化系列]Linux 性能优化 -- CPU 性能篇(三) Linux 软中断 [1]相关概念 [1.1]中断 中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力:为了减少 ...

  7. Linux性能优化实战学习笔记:第十讲==中断

    Linux性能优化实战学习笔记:第十讲 一.坏境准备 1.拓扑图 2.安装包 在第9节的基础上 在VM2上安装hping3依奈包 ? 1 2 3 4 5 6 7 wget http://www.tcp ...

  8. 【Linux 性能优化系列】Linux 性能优化 -- CPU 性能篇(一) 平均负载、上下文切换、CPU 使用率

    [Linux 性能优化系列]Linux 性能优化 -- CPU 性能篇(一) 平均负载.上下文切换.CPU 使用率 [1]相关概念 [1.1]平均负载 平均负载是指单位时间内,系统处于可运行状态和不可 ...

  9. 开发人员如何解决Linux性能优化之痛?

    这些问题或者场景,你是否曾经遇到过? •  流量高峰期,服务器CPU使用率过高报警,你登录Linux上去top完之后,却不知道怎么进一步定位,到底是系统CPU资源太少,还是程序并发部分写的有问题? • ...

最新文章

  1. 问一下大家个3D问题:旋转和缩放以及平移中如何插值矩阵?
  2. antd vue form 手动校验_Vue 开发者不可错过的五款开源扩展组件
  3. 剑指Offer之栈的压入、弹出序列
  4. 套接字Select I/O模型
  5. 有关 iOS 的开发证书、应用标识、设备标识、配置文件以及密钥 #DF...
  6. 成立出版社的条件_创始人亲述:法国鸿飞文化出版社的诞生故事和做书心得
  7. 重启报错_Win10蓝屏,提示收集错误信息,反复重启报错
  8. python安装matlab库_[python][matlab]在python36上安装matlab2015b引擎
  9. Android编程之Toast官方使用说明译文
  10. SWIFT显示底部的工具条
  11. Java并发包一览图
  12. 荐书|图解深度学习与神经网络:从张量到TensorFlow实现
  13. easyExcel实现excel文件上传和下载
  14. 怎样在命令行下检测和清除恶意软件
  15. 《极限竞速地平线4》Teredo不合格解决
  16. 听老外吐槽框架设计,Why I Hate Frameworks?
  17. github的Whoa there!问题
  18. Android 7.0图片裁剪问题
  19. 航测大数据量处理_上海无人机航测收费标准大数据应用中心
  20. 从零开始学架构——架构基础

热门文章

  1. C++ : sin、cos、tan、arctan的使用
  2. 接口测试-公司内部培训资料
  3. 研究速递:使用AI应对腐败的潜力和风险
  4. windowns server 2012 R2 启动U盘制作
  5. ​宝尊电商年亏2亿:阿里又成大股东 软银大幅减持
  6. IE加载OCX插件崩溃原因之栈溢出问题
  7. python3-编程题之商品价格计算器
  8. Linux 远程桌面 速度快,虫洞TCP加速,提升远程桌面和SSH访问速度
  9. 谷歌语音对接-GoogleAssistant-smart-home
  10. 赏红叶,是金秋心旷神怡之事