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不是一個業務??怎麼越想越亂,一定是我智商不夠。題主能解答下我的疑惑嘛
推薦閱讀: