我眼中的 Nginx(六):深入 Nginx/Openresty 服务里的 DNS 解析
轉自:https://www.upyun.com
DNS 解析在 Nginx/OpenResty 的服務里是不可分割的一個功能,本文主要來介紹下 Nginx 和 OpenResty 服務里的一些不同的 DNS 解析方式以及它們之間的優(yōu)缺點。
配置解析階段
很多時候我們會在 Nginx 配置文件里配置上一些域名,比如配置我們的上游服務器。
upstream example.com {server foo.example.com; }對于這類域名,Nginx 會在配置解析階段就將其解析出來,接下來(請求處理過程)使用的都是當時解析得到的 IP。Nginx 核心有一個函數(shù) ngx_parse_url,負責對 url 格式進行分析,包括解析出主機名,端口號以及 URL path 等。針對 IPv4 的情況,它會調(diào)用 ngx_parse_inet_url進行具體的解析任務,如果必要,最終它會調(diào)用到 ngx_inet_resolve_host進行域名解析,ngx_inet_resolve_host 大多情況下會使用 getaddrinfo 進行解析,最終向 /etc/resolv.conf 下所配置的 DNS server 發(fā)起解析請求。
歸納來說這個解析過程有兩個特點,一是使用了系統(tǒng)配置的 DNS server;二是解析過程是同步且阻塞的,因此這種解析方式僅在 Nginx 配置解析階段會被使用。另外這種解析方式的缺點就是只解析一次,所以如果在 Nginx 運行過程中域名解析發(fā)生了改變也是無法感知到的,除非手動重啟 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 指令里寫明需要代理的域名(即不使用變量的方式),那么域名解析就會發(fā)生在配置解析階段了,即上面所講的過程。這其實也是一種實現(xiàn)動態(tài) upstream 的方式。
這套運行時 DNS resolver 其實是一個 DNS client 的角色,由它自己組織查詢報文并發(fā)送給目標 DNS 服務器,同時支持解析 IPv6 地址(從 1.5.8 開始),支持反向地址解析和 SRV 解析。它把對每個域名的解析抽象為一棵紅黑樹的節(jié)點,包括任何必要的信息。同時這棵紅黑樹也充當著緩存,查詢時會以域名作為 key,如果對應緩存是新鮮的,即會復用緩存,并且會對解析得到的地址順序進行一定的回轉后再提供給上層使用。如果沒有緩存或者緩存過期,新的 DNS 請求會被構建并且發(fā)送。
當然,很多時候這套運行時的 DNS resolver 也不能完全滿足需求:
Cosocket
Cosocket 是 lua-nginx-module 提供的最強有力的接口(個人來看沒有之一)。它的 connect方法同樣支持傳入域名,之后會調(diào)用上面介紹的 Nginx 運行時 resolver 來解析對應域名,然后隨機挑選一個 IP 作為本次連接的目標 IP 地址。由于是使用的 Nginx 運行時 resolver ,如果 DNS resolver 無法正常進行解析,則利用 Cosocket 構建的服務也都會受到影響。
lua-resty-dns
OpenResty 官方開源的 lua-resty-dns 是利用 Cosocket 實現(xiàn)的一套百分百非阻塞的 DNS resolver,它僅僅充當了一個 DNS 解析器,沒有任何其他的附加功能,包括緩存。
前面介紹過 Nginx 運行時 DNS resolver 在很多時候是有諸多的不便的,而 lua-resty-dns 則給我們留了很多的擴展空間:
目前 OpenResty 生態(tài)圈已經(jīng)有一些基于lua-resty-dns 實現(xiàn)的加強版實現(xiàn),比如 Kong 的 lua-resty-dns-client。
總的來說,每一種 DNS 解析方式都有它適用的場景,也有它自己的不足,沒有最好的,只有最合適的。在程序設計的時候,需要找到最合適自己業(yè)務場景的方式,才能最大程度地保障服務的可用性和可靠性,避免帶來一些災難。
總結
以上是生活随笔為你收集整理的我眼中的 Nginx(六):深入 Nginx/Openresty 服务里的 DNS 解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: resty资源推荐
- 下一篇: source insight 支持lua