標籤:
公司內網環境中許多調用資源(資料庫、web介面等)都是通過內網DNS服務來進行網域名稱-IP的映射。
但經常出現DNS映射修改完畢後,應用中串連的資源遲遲沒有變更。
以前一直籠統的認為是linux的dns緩衝導致,今天做了一次完整的分析,結果如下:
1、Linux系統的本地DNS的緩衝
CentOS系統本身並不包含DNS的緩衝機制,除非安裝並啟動了nscd服務(name server cache daemon)。
nscd服務啟動後會預設為本地的所有dns解析做一層緩衝,到期時間預設為3600秒,重啟應用程式也不會重設nscd的緩衝,除非用/etc/init.d/nscd reload,強制重新整理nscd緩衝。
開啟nscd服務可以大大降低應用程式請求DNS服務的頻率,同時一定程度上可以對DNS服務的故障有一定容錯。但缺點非常明顯,DNS服務的映射改變無法即時的被應用程式感知,每次修改映射後都必須在所有用戶端機器reload nscd。
以上結論通過DNS服務日誌得到驗證。
2、JVM虛擬機器的本地DNS緩衝
實現在java.net.InetAddress的一個簡單的DNS緩衝機制,以前被誤認為是Linux的DNS緩衝,jdk6/7中預設為緩衝30秒。
緩衝範圍為JVM虛擬機器進程,也就是說同一個JVM進程中,30秒內只會為一個網域名稱請求DNS伺服器一次,可以大大降低應用程式對DNS解析的網路損耗和對DNS服務產生的壓力。
以上結論通過JAVA測試程式和DNS服務日誌得到驗證。
3、長串連的處理(資料庫連結、redis串連、zookeeper、activeMQ串連等)
根據1、2兩點結論,當內網DNS服務某一個網域名稱映射修改後,應用程式最多在30秒內就會響應該變化。但實際確不是如此,原因就是很多資源是“長串連”方式。
比如資料庫連接池這種就是典型的長串連,為了保證串連池效率,我們也不能把單個串連的有效期間設的太短。這就導致了這類長串連無法快速響應DNS伺服器的映射改變。
解決辦法只有一個:DNS伺服器的映射變更後,需要對應用程式做重啟,以便讓長串連按照新的DNS映射來進行建立。
以上結論通過JAVA測試程式和DNS服務日誌得到驗證。
饒了一圈,最後還是回到原點:
為了保證應用程式裡的這些長串連資源能夠及時響應DNS映射的改變,目前還是得靠重啟應用來解決。
Linux內網環境DNS修改網域名稱指向,JAVA應用程式能否即時切換的問題總結