转自:https://www.upyun.com

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/Openresty 服务里的 DNS 解析相关推荐

  1. nginx+php+memcache高速缓存openresty)

    一.php源码编译 1.软件下载:软件下载 (这里使用的时php-7.4.6版本) 如果系统已经装了php请先卸载,以免与源码编译冲突 [root@server1 ~]# yum install bz ...

  2. Linux的Nginx六:源码|安装

    源码 概述 可以使用yum install tree来安装tree命令,就可以显示出文件的树结构 可以看出共有10 directories, 265 files,Nginx的主要模块是Core.eve ...

  3. Linux基础学习六:Nginx的使用教程

    Nginx (发音:engine x) 是一个高性能的HTTP和反向代理web服务器.它有2个常见的应用场景: 反向代理Tomcat集群并实现负载均衡 充当静态资源(html.js.css.图片)服务 ...

  4. nginx 支持php-fpm,nginx php-fpm安装配置以支持PHP

    nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端. nginx一般是把请求发fastcgi管理进程处理,fascgi管 ...

  5. redhat nginx php mysql_redhat7+nginx+mysql+php

    一. 源码安装nginx 1.安装基础依赖包 yum -y install gcc automake autoconf libtool make gcc gcc-c++ openssl openssl ...

  6. nginx 返回动态Html,Nginx负载均衡 -Nginx动态更新upstream

    Nginx 的配置是启动时一次性加载到内存中的,在实际的使用中,对 Nginx 服务器上游服务器组中节点的添加或移除仍需要重启或热加载 Nginx 进程.在 Nginx 的商业版本中,提供了 ngx_ ...

  7. Nginx 负载均衡和缓存服务实战

    转自:泥瓦匠BYSocket sf.gg/a/1190000014893012 基础篇 一.环境 二.Nginx是什么? 三.我们为什么选择Nginx? 三.安装与目录 四.基本配置 五.模块 场景实 ...

  8. (三)Linux环境部署(Centos+Nginx+Tomcat+Mysql) - Nginx环境搭建

    因为在网上发现系统性.严谨(特别是在安全方面)的Linux部署方面的参考文章很少,于是整理以下六篇Linux环境部署的系列性文章,其为本人在实践中,完整的搭建一个基于Linux系统上Centos+Ng ...

  9. 「微服务架构」基于NGINX的三种微服务参考架构

    作者注:本博文是系列文章的第一篇: Introducing the NGINX Microservices Reference Architecture (this post) MRA, Part 2 ...

最新文章

  1. Java API —— Collections类
  2. java在哪个文件夹_JVM具体在哪个文件夹下的
  3. Cesium原理篇:7最长的一帧之Entity(上)
  4. 【muduo源码分析 】 MutexLock和MutexLockGuard封装
  5. python——学习登录用户和密码的判断——1
  6. STM32 IIC实验中关于AT24Cxx的读写
  7. 【机器学习】网格搜索、随机搜索和贝叶斯搜索实用教程
  8. qt自定义控件之简单曲线图表控件
  9. Web组件开发一 分层详解 和模块化
  10. 双人聊天php,js实现双人五子棋小游戏
  11. 创建github或者gitee(国内版github)账户
  12. LeetCode714:买卖股票的最佳时机含手续费
  13. 大文件传输软件-镭速——MAC版分享
  14. html5border设置彩色,css中border颜色不同怎么设置?
  15. 《魔兽争霸3》战网命令详解
  16. MT4-EA自动化交易研究笔记(2022-04-22)
  17. 网页上facebook分享功能的具体实现
  18. 下载微信公众号或订阅号的文章封面图片
  19. T0001.数据结构面试题---栈---获取最小值
  20. 百度小程序和微信小程序,开放与封闭之争

热门文章

  1. 【CCNA】思科PPP身份验证(PAP单向认证与CHAP单向认证)
  2. Forefront_TMG_2010-TMG发布SSL OWA Exchange 2010
  3. CodeForces - 1332D Walk on Matrix(构造)
  4. HihoCoder - 1441 后缀自动机一·基本概念(模拟,后缀自动机入门好题)
  5. 51Nod - 1024 矩阵中不重复的元素(数学)
  6. (转)网络流-最大流 SAP算法(模板)
  7. EXE和SYS通信IOCTL方式
  8. IOCP不可忽视的细节
  9. 网狐棋牌(五) TCPSocketEnging分析
  10. 浅谈 FTP、FTPS 与 SFTP