Linux內網環境DNS修改域名指向,JAVA應用程式能否實時切換的問題總結

baibaluo發表於2015-07-04

公司內網環境中許多呼叫資源(資料庫、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對映的改變,目前還是得靠重啟應用來解決。

相關文章