DNS(domain name system 域名系统),首先,它是一项应用层服务,可以将互联网中的主机名解析为IP地址,通常DNS是由多台DNS服务器搭建起来的分布式数据库,因此一个完整的域名解析的过程就是一个查询分布式数据库的过程。
DNS协议由两部分组成:
【1】用于根据主机名查询对应IP地址的请求和响应协议(域名解析)
【2】域名服务器之间用于交换资源记录的协议(区域传输)
DNS协议运行在UDP上,熟知端口号为53。
Mail.cctv.com. ————> 三级域名.二级域名.顶级域名.根域名。根域名就是一个点“.”
域名服务器分类
【1】根域名服务器(告诉本地域名服务器/LDNS下一步找哪一个顶级域名服务器)
【2】顶级域名服务器(管理在该域名服务器注册的所有二级域名)
【3】权限域名服务器(负责一个区的域名服务器)
【4】本地域名服务器(属性->ipv4…指定的“首选DNS”就是LDNS)
主机向本地域名服务器发送请求后,进行递归查询——我替你问
而域名服务器向其他域名服务器查询则采用迭代查询——你问别人
为了提高DNS查询效率,并减轻根域名服务器的负荷以及网络中DNS查询报文 的数量,在域名服务器中广泛使用了高速缓存域名服务器。
【1】浏览器正式向DNS服务器发送域名解析请求之前,首先查询浏览器的域名系统缓存,没有则去本地域名解析文件hosts查看,没有才会进行查询(dns)
Http1.1增加了host,用于实现虚拟主机,可以用来做负载均衡(同一台主机服务器部署多个网站,TCP连接到同一端点(目标主机的服务器端口),但是会根据host分发到具体的网站)
【2】客户端先查询本地域名服务器(LDNS),每个LDNS服务器都有缓存
【3】本地域名服务器没查到,则去查询根域服务器。根域服务器会返回顶级域名服务器的ip地址,顶级域名服务器返回目标区域的权威域名服务器的ip地址。最终权威域名服务器会给出最终结果。
本地服务器是递归查询,根域、顶级域名服务器是迭代查询,因为根域、顶级域名服务器处于高层次域,可以被所有子服务器发送解析请求,而本地服务器通常只对应一个ISP范围的用户。所以低层次服务器能够承受递归查询的代价,而高层次的服务器无法承受
共同实现DNS分布式数据库的所有DNS服务器存储了资源记录,每个DNS回答报文都会保证至少一条资源记录。
一个资源记录就是一个四元组(name,value,type,ttl),记录可以简单的看作一个附带过期时间的键值对(name->value),其中键值对的意义取决于type。
【1】A记录,代表主机名到IP地址的映射(a.b.c.com -> 145.33.91.123)
【2】NS记录,代表顶层域到该域的权威DNS服务器主机名的映射(a.com -> dns.a.com),用于沿着查询链来路由能够解析域名的DNS服务器
【3】CNAME记录,将别名映射为一个主机名对应的规范主机名(a.com->aa.a.com)
【4】MX记录,返回邮件服务器的规范主机名(a.com -> mail.a.com)
【5】PTR反向解析,根据ip地址查询域名
DNS进行域名解析服务时,使用UDP协议,主要是为了效率(缩短整体的响应时间),而且报文的内容一般都不长,如果太长会被直接截断(因为DNS没有能够标识报文ID的字段,默认请求和应答都是使用一个报文)
一些TCP实现上,当收到一个截断的UDP响应包,一般会使用TCP重新请求发起DNS请求
如果需要防范DNS欺骗,需要对DNS报文进行数字签名,但是这造成DNS报文负载变大,不得不使用TCP进行传输(DNS over HTTPS)
由于DNS是一个分布式的系统,而且防止故障通常需要多台服务器搭建集群,一旦涉及数据同步就需要进行TCP传输数据(这个过程称为区域传送),因为数据同步要求数据的准确性和传输可靠性,而且数据量较多。
当一个区域的辅助域名服务器启动时,需要从主域名服务器传送区域信息,区域传输可能由计时器引起,也可能因DNS通知引起。完整区域传输通常使用UDP因为可能超过单个UDP报文上限。增量区域传输通常优先采用UDP,如果响应消息太大就会切换为TCP。
当使用UDP时,解析器和服务器应用程序必须在应用层保证可靠性。
DNS也是实现负载均衡的一种方案。
为了舒缓主服务的压力,部署一些从服务器,并且这些服务器具有不同的IP地址,这些IP地址与同一个规范主机名相关联,DNS数据库存储这些IP地址集合,当一个DNS请求过来,DNS服务器(或者使用一个缓存的DNS记录的代理服务器)根据某种算法,选取某个IP地址进行回应,以达到反向代理和负载均衡的效果。
一个URL 协议://域名:端口号/请求资源地址?参数
如果协议、端口、域名任何一个不同则认为跨域
CDN内容分发网络,本质上是一种缓存,CDN管理着多个不同地理位置主机的资源,大多数CDN基于截获和重定向本地域名服务器(LDNS)的DNS请求来实现。用户想要访问一个静态资源,它不必向源服务器请求资源,而是向一个地理上更近的CDN服务器去请求。
使用场景:
面向内部的网站,资源文件和业务代码比较耦合,script引用往往指向站内文件(相对地址)。这种方式的优点是发布简单、对服务器要求小。但是系统访问量增加后,为了减少服务器的压力,需要将服务器分离为资源服务器和应用服务器,这个时候各种静态资源的应用就需要改成绝对路径,指向对应的资源服务器。
提升用户发出请求后资源的响应速度、分担服务器压力、节省空间和流量。
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
当服务器请求js的时候直接去最近的百度CDN服务器找,而不是当前自己的服务器
CDN的加速策略和通常域名绑定,通过域名访问资源,首先是通过DNS调度系统查找离用户地理上最近的CDN节点(边缘服务器)的ip地址。通过IP地址访问资源,如果CDN服务器上没有缓存资源,则会到源站请求资源,并缓存到CDN节点上。
大致流程:
用户向资源发出请求,首先会向本地DNS服务器(LDNS)发出DNS请求,本地域名服务在缓存中没有查询出结果后将递归查询,最终得到一个CNAME记录,这个CNAME最终会被解析到一台CDN专用的DNS服务器。
用户向CDN的全局负载均衡设备发出请求(递归),CDN全局负载均衡设备根据用户的IP地址、请求的URL选择一台用户所属区域的区域负载均衡设备,告诉用户向该设备发送请求,区域负载均衡设备向用户返回一台缓存服务器的IP地址。最终的结果就是,全局负载均衡设备向用户返回了一台CDN缓存服务器的IP地址。
如果该IP地址对应的服务器节点缓存了该资源,则会将数据直接返回给用户,请求结束。否则,该服务器节点将向源站发出对该资源的请求(当前缓存服务器依次向上一级服务器请求,直到请求达到源服务器)。获取资源后,结合用户(CDN服务购买者)自定义配置的缓存策略将资源缓存在该服务器节点。
总结:
DNS服务器可以根据用户IP地址(如分析地理位置)将域名解析到合适的缓存服务器IP地址,实现用户就近访问,而使用CDN服务,其实就是将域名解析的请求委托为CDN专用的DNS服务器,实现内容加速查询。(CDN实现多种多样,以上只是以DNS为例)