张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护。Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技术的研究;曾为 ngx_lua 贡献源码,在 Nginx、ngx_lua、CDN 性能优化、日志优化方面有较为深入的研究。

DNS 解析在 Nginx/OpenResty 的服务里是不可分割的一个功能,本文主要来介绍下 Nginx 和 OpenResty 服务里的一些不同的 DNS 解析方式以及它们之间的优缺点。

配置解析阶段

很多时候我们会在 Nginx 配置文件里配置上一些域名,比如配置我们的上游服务器。

  • upstream example.com {
  • server foo.example.com;
  • }

对于这类域名,Nginx 会在配置解析阶段就将其解析出来,接下来(请求处理过程)使用的都是当时解析得到的 IP。Nginx 核心有一个函数 ngx_parse_url,负责对 url 格式进行分析,包括解析出主机名,端口号以及 URL path 等。针对 IPv4 的情况,它会调用 ngx_parse_inet_url进行具体的解析任务,如果必要,最终它会调用到 ngx_inet_resolve_host进行域名解析,ngx_inet_resolve_host 大多情况下会使用 getaddrinfo 进行解析,最终向 /etc/resolv.conf 下所配置的 DNS server 发起解析请求。

归纳来说这个解析过程有两个特点,一是使用了系统配置的 DNS server;二是解析过程是同步且阻塞的,因此这种解析方式仅在 Nginx 配置解析阶段会被使用。另外这种解析方式的缺点就是只解析一次,所以如果在 Nginx 运行过程中域名解析发生了改变也是无法感知到的,除非手动重启 Nginx 服务。

运行时 DNS resolver

Nginx 核心提供了一套供运行时使用的 DNS 解析机制,它充分契合 Nginx 的事件模型,同样是异步非阻塞的,并且提供了缓存机制。http、stream 和 mail 模块分别提供了配置指令(比如 http 模块提供的 resolver),供我们配置相关 DNS server 地址等信息。

下面这个简单的反向代理配置,就会在进行代理前解析 http://www.upyun.com 这个域名。

  • location / {
  • set $myupstream www.upyun.com;
  • proxy_http_version 1.1;
  • proxy_set_header Connection "";
  • proxy_pass http://${myupstream}/index.html;
  • }

注意如果直接在 proxy_pass 指令里写明需要代理的域名(即不使用变量的方式),那么域名解析就会发生在配置解析阶段了,即上面所讲的过程。这其实也是一种实现动态 upstream 的方式。

这套运行时 DNS resolver 其实是一个 DNS client 的角色,由它自己组织查询报文并发送给目标 DNS 服务器,同时支持解析 IPv6 地址(从 1.5.8 开始),支持反向地址解析和 SRV 解析。它把对每个域名的解析抽象为一棵红黑树的节点,包括任何必要的信息。同时这棵红黑树也充当着缓存,查询时会以域名作为 key,如果对应缓存是新鲜的,即会复用缓存,并且会对解析得到的地址顺序进行一定的回转后再提供给上层使用。如果没有缓存或者缓存过期,新的 DNS 请求会被构建并且发送。

当然,很多时候这套运行时的 DNS resolver 也不能完全满足需求:

  1. 无法配置主备 DNS 服务器地址,我们在 resolver 指令里配置的地址都会按顺序被轮询到。
  2. 无法在 DNS 服务器故障或者网络质量不佳的情况下复用陈旧的缓存,这可能导致上层服务不可用。
  3. 每个 Nginx worker 进程独享解析缓存。

Cosocket

Cosocket 是 lua-nginx-module 提供的最强有力的接口(个人来看没有之一)。它的 connect方法同样支持传入域名,之后会调用上面介绍的 Nginx 运行时 resolver 来解析对应域名,然后随机挑选一个 IP 作为本次连接的目标 IP 地址。由于是使用的 Nginx 运行时 resolver ,如果 DNS resolver 无法正常进行解析,则利用 Cosocket 构建的服务也都会受到影响。

lua-resty-dns

OpenResty 官方开源的 lua-resty-dns 是利用 Cosocket 实现的一套百分百非阻塞的 DNS resolver,它仅仅充当了一个 DNS 解析器,没有任何其他的附加功能,包括缓存。

前面介绍过 Nginx 运行时 DNS resolver 在很多时候是有诸多的不便的,而 lua-resty-dns 则给我们留了很多的扩展空间:

  1. 提供主备 DNS 服务器地址 —— 结合像 lua-resty-checkups 这样的工具可以很容易的维护主备 DNS 服务器地址,包括进行心跳检测。
  2. 进程间共享缓存 —— 结合使用 lua-nginx-module 提供的共享内存字典,可以非常容易地管理缓存。
  3. 故障时使用陈旧缓存 —— 在 lua-resty-dns 报告异常时再次使用缓存即可(只要缓存拷贝没有被强行淘汰)。

目前 OpenResty 生态圈已经有一些基于lua-resty-dns 实现的加强版实现,比如 Kong 的 lua-resty-dns-client。

总的来说,每一种 DNS 解析方式都有它适用的场景,也有它自己的不足,没有最好的,只有最合适的。在程序设计的时候,需要找到最合适自己业务场景的方式,才能最大程度地保障服务的可用性和可靠性,避免带来一些灾难。

推荐阅读:

我眼中的 Nginx(五):Nginx - 子请求设计之道​
我眼中的 Nginx(四):是什么让你的 Nginx 服务退出这么慢?​
我眼中的 Nginx(三):Nginx 变量和变量插值
我眼中的 Nginx(二):HTTP/2 dynamic table size update​
我眼中的 Nginx(一):Nginx 和位运算​

我眼中的 Nginx(六):深入 Nginx/Openresty 服务里的 DNS 解析的更多相关文章

  1. Nginx(六):Nginx HTTP负载均衡和反向代理的配置与优化

    一.什么是负载均衡和反向代理 随着网站访问量的快速增长,单台服务器已经无法承担大量用户的并发访问,必须釆用多台服务器协同工作,以提高计算机系统的处理能力和计算强度,满足当前业务量的需求.而如何在完成同 ...

  2. 用lua扩展你的Nginx(整理)-----openresty

    用lua扩展你的Nginx(整理) 首先得声明.这不是我的原创,是在网上搜索到的一篇文章,原著是谁也搞不清楚了.按风格应该是属于章亦春的文章. 整理花了不少时间,所以就暂写成原创吧. 一. 概述 Ng ...

  3. web 部署专题(六):nginx 安装(二) linux

    https://www.cnblogs.com/quzq/p/12131696.html 基础篇 一.环境 服务器版本:CentOS 7.2 为了保证学习阶段不遇到奇怪的事情,请保证以下四点(大神选择 ...

  4. Nginx源码研究六:NGINX的配置文件分析

    上一篇写到nginx的各个模块的配置信息的存储结构,大体描述了对配置信息的配置项生成,定制,初始化过程.这里重点研究实现定制的过程,所谓实现定制,这里指的是,nginx系统提供使用者定义nginx的配 ...

  5. Nginx详解二十六:Nginx架构篇之性能优化

    一.性能优化考虑点 1.当前系统结构瓶颈 通过压力测试观察指标.日志检测.性能分析 2.了解业务模式 接口业务类型.系统层次化结构 3.性能与安全 二.ab接口压力测试工具 1.安装:yum -y i ...

  6. Nginx详解十六:Nginx场景实践篇之缓存服务

    缓存类型: 服务端缓存 代理缓存 客户端缓存 Nginx代理缓存 配置语法 使用之前需要先定义一个proxy_cache_path配置语法:proxy_cache_path path [levels= ...

  7. 第一次项目上Linux服务器(六:Nginx安装及相关命令(转))

    1.下载nginx 方法一 wget http://nginx.org/download/nginx-1.11.6.tar.gz 方法二 http://nginx.org/en/download.ht ...

  8. 第十六篇 nginx主配置文件参数解释

    # 指定拥有运行nginx权限的用户 #user nobody; # 指定开启的进程数,建议设置为CPU核心数 worker_processes ; # 指定全局错误日志级别,包括:debug/inf ...

  9. Nginx(六):配置解析之location解析

    nginx成为非常流行的代理服务软件,最根本的原因也许是在于其强悍性能.但还有一些必要的条件,比如功能的完整,配置的易用,能够解决各种各样的实际需求问题,这些是一个好的软件的必备特性. 那么,今天我们 ...

随机推荐

  1. SQL Server中表锁定的原理及解锁演示

    有几个朋友留言建议结合例子来演示一下, 上篇已经说过锁的几种类型, 可以利用系统动态视图sys.dm_tran_locks查看到,重要的栏位如下: resource_type 被锁的资源类型(Data ...

  2. Maven项目管理工具

    Maven项目管理工具 白面郎君 Svn eclipse maven量级 1 Maven的简介 1.1 什么是maven 是apache下的一个开源项目,是纯java开发,并且只是用来管理java项目 ...

  3. 树莓派配置watchdog

    安装watchdog apt install watchdog 编辑/etc/modules,添加bcm2708_wdog 编辑/etc/watchdog.conf watchdog-device = ...

  4. LogicalDOC office预览中文乱码的问题

    近期在试用LogicalDOC,一个文档管理系统. 上传的office文件预览中文乱码 问题原因是LibreOffice缺少对应的中文字体导致,只需要把对应的中文字体拷贝到/opt/libreoffi ...

  5. Zookeeper学习

    http://www.cnblogs.com/caosiyang/archive/2012/11/09/2763190.html   http://www.cnblogs.com/haippy/tag ...

  6. centos tftp和samba的安装与配置

    Tftp服务器的安装于配置 1 安装: 命令:#yum –y install tftp 2 安装完毕之后,将tftp服务器设置为开机启动,方法:(命令)#setup→选择system server→选 ...

  7. ehcache与redis的比较与应用场景分析(转)

    ehcache直接在jvm虚拟机中缓存,速度快,效率高:但是缓存共享麻烦,集群分布式应用不方便.redis是通过socket访问到缓存服务,效率比ecache低,比数据库要快很多,处理集群和分布式缓存 ...

  8. CSS+DIV定位分析(relative,absolute,static,fixed)

    在用CSS+DIV进行布局的时候,一直对position的四个属性值relative,absolute,static,fixed分的不是很清楚,以致经常会出现让人很郁闷的结果.今天研究了一下,总算有所 ...

  9. 解决mongodb的安装mongod命令不是内部或外部命令

    1:安装 去mongodb的官网http://www.mongodb.org/downloads下载32bit的包 解压后会出现以下文件 在安装的盘C:下建立mongodb文件夹,拷贝bin文件夹到该 ...

  10. python爬取网易云周杰伦所有专辑,歌曲,评论,并完成可视化分析

    ---恢复内容开始--- 去年在网络上有一篇文章特别有名:我分析42万字的歌词,为搞清楚民谣歌手们在唱些什么.这篇文章的作者是我大学的室友,随后网络上出现了各种以为爬取了XXX,发现了XXX为名的文章 ...