nginx的dns緩存問題?

如題,使用nginx做反向代理,將請求發送到一個域名(例如: proxy_pass http://www.test.com 該域名對應的IP是A) ,剛開始運行一切正常,但是當運行了一段時間以後,域名對應的IP變了(例如http://www.test.com對應的IP由A變為B),nginx的轉發仍然還在向原先的IP發送請求,導致業務中斷,此時reload nginx後才會重新恢復正常,且日誌顯示數據轉發到新的IP B了,請問如何讓nginx自動去重新解析域名,而不用每次出現問題了人工去reload? 請大神指點


時隔幾個月,遇到了其他問題,忽然找到了解決這個問題的方法,現在分享一下

背景:

此處只針對nginx向後端做代理,且後端代理為域名形式 的這種情況做分析

1、正常情況下 啟動nginx後(或者 -t / reload nginx時),nginx會通過操作系統配置的DNS伺服器去解析域名對應的IP

2、當nginx配置文件中的所有涉及到的域名都可以被正常解析到以後,才能啟動(或者檢查/重新載入)通過

3、這裡需要提醒一點,在 ../sbin/nginx -t 或者 ../sbin/ngins -s reload 只是檢查域名是否可以解析通過,並不會在此時緩存域名對應IP,只有在通過nginx第一次向proxy_pass後端對應的域名做代理數據轉發時,這裡nginx會通過操作系統配置的DNS伺服器解析域名,此時才會緩存域名對應的IP,且會緩存很長時間,甚至一個月(整個過程均有生產實例證明,且抓包驗證)

我遇到的問題:

生產的實例

1、我們內網的數據通過nginx轉發到第三方合作公司對應的域名,此處簡稱為 域名A

2、第三方公司的域名A做了CDN,對應多個IP(IP1,IP2,IP3...),且隨時都有可能因某種原因,丟棄其中一個IP

3、某一天該第三方公司將他們的域名A對應的地址IP3廢棄不用了,域名不再往IP3上解析了

4、但是我們的nginx因為曾經請求域名A時緩存了IP3,導致後續的許多交易數據仍舊是給IP3發送,造成交易失敗,這種情況在我們沒有reload nginx之前,存在了2周左右,說明nginx緩存這個IP3緩存了很長時間,這就是造成了我們交易失敗的原因(當時排查了好幾天),後來多方聯繫核對後,才知道第三方公司早在3周前就廢棄了這個IP3,(可能為了全網的DNS都刷新,域名A不再向IP3解析後,但是IP3所對應的伺服器還繼續沿用了一段時間,所以我們是在廢棄後的第二周才開始報錯)

分析與解決:

1、既然是因為nginx緩存域名對應IP的DNS記錄造成的,那麼怎麼才能解決呢,方法有兩種:

(1)、手動reload nginx,讓nginx重新解析域名,這個時候解析到域名對應的IP是最新的,不會包含已經被廢棄的IP3

(2)、設置nginx的DNS緩存時間,比如600s失效,然後重新去解析

2、方法(2)當然是最好的,但是nginx的DNS緩存時間在哪裡設置呢,我沒有找到!

3、但是我找到另外一種方法 -- nginx 的 resolver

nginx的resolver 解決方案

1、默認nginx會通過操作系統設置的DNS伺服器(/etc/resolv.conf)去解析域名

2、其實nginx還可以通過自身設置DNS伺服器,而不用去找操作系統的DNS

3、下面來講一個這個resolver

示例配置如下:

server {
listen 8080;
server_name localhost;
resolver 114.114.114.114 223.5.5.5 valid=3600s;
resolver_timeout 3s;
set $qq "www.qq.com";
location / {
proxy_pass http://$qq;
}
}

參數說明:

# resolver 可以在http全局設定,也可在server裡面設定

# resolver 後面指定DNS伺服器,可以指定多個,空格隔開

# valid設置DNS緩存失效時間,自己根據情況判斷,建議600以上

# resolver_timeout 指定解析域名時,DNS伺服器的超時時間,建議3秒左右

#注意:當resolver 後面跟多個DNS伺服器時,一定要保證這些DNS伺服器都是有效的,因為這種是負載均衡模式的,當DNS記錄失效了(超過valid時間),首先由第一個DNS伺服器(114.114.114.114)去解析,下一次繼續失效時由第二個DNS伺服器(223.5.5.5)去解析,親自測試的,如有任何一個DNS伺服器是壞的,那麼這一次的解析會一直持續到resolver_timeout ,然後解析失敗,且日誌報錯解析不了域名,通過頁面拋出502錯誤。

#重點:如上例,在代理到後端域名http://www.qq.com時,千萬不要直接寫在proxy_pass中,因為server中使用了resolver,所以必須先把域名定義到一個變數裡面,然後在 proxy_pass http://$變數名,否則nginx語法檢測一直會報錯,提示解析不了域名

後記

整個過程親測,沒有問題

如果有其他更好的方式或者見解,請回復一起探討哈


審題兩遍,好像沒看懂題目的意思。

題主的意思是nginx做反向代理,伺服器A,B沒做負載均衡?域名解析怎麼一會解析成A 一會解析成B,然後A,B不是一個業務??怎麼越想越亂,一定是我智商不夠。題主能解答下我的疑惑嘛


推薦閱讀:

TAG:Nginx | 反向代理 | Linux運維 |