The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

使用 Java 開發的系統需注意 DNS 快取的問題 (快取一輩子)

之前有替客戶安裝一套 IBM OmniFind Yahoo! Edition 在 Linux 環境下,採用的 Java 版本為 1.5.0,最近客戶的主機換機房了導致 IP 變更,搬過去之後發現這個搜尋引擎還能夠查詢,但是卻無法對原本網站進行索引動作,就算我們重新將索引重建,還是無法所以成功,所呈現的訊息都是無法連接至網站,但是本機設定的 DNS 並沒有問題,連線、防火牆也沒問題,即便設定了 /etc/hosts 也還是連不上,這實在太奇怪了,查到最後才發現到原來是 JDK 1.5 以前預設會將 DNS 快取一輩子 (cache forever),才會導致原本網站怎麼樣都連不上的情況。

以下是我找到問題癥結點的方法:

  1. IBM OmniFind Yahoo! Edition 的管理介面新增一個網站,讓系統對該網站建立 HTTP 連線
  2. 使用 netstat -natp | grep java 指令查詢所有已建立連線
  3. 得知原來 IBM OmniFind Yahoo! Edition 連接到了該網站的舊 IP 位址
  4. 確診為 DNS 問題

接著就開始朝著 DNS 問題打轉:

  1. 利用 host 指令測試網址查詢出的 IP 是否正確 ==> 正確無誤
  2. 利用 telnet 測試網站 IP 的 Port 80 是否能正常連線 ==> 可以正常連線,所以不是防火牆的問題
  3. 設定 /etc/hosts 設定新的網址/IP對應 ==> 系統還是抓到錯誤的 IP 位址

作業系統這邊都無法解決問題,應該就只剩下應用系統的問題了,接著就開始找為什麼 java.exe 無法連線到網址,但所有其他程式都可以連線呢?難道 Java 本身實做了某種快取機制嗎?果不其然,上網搜尋 java dns cache 馬上找到答案!

原來是 JDK 從 1.0 ~ 1.5 裡有個 networkaddress.cache.ttl 參數 ( 在 java.security 設定檔 ),這裡定義了當 Java 在對網路進行名稱解析時的快取時間,預設為竟然為 -1 (cache forever),而且又這麼剛好這台伺服器超級穩定,主機搬家後重來都沒有重開過,所以這些 DNS 快取資料完全沒有清空,所以還是抓到了錯誤的 IP 位址。… 這又再次證明即便在 Linux 裡 3R 策略還是奏效的 XD …

新版的 Java 已經修改了 DNS Cache TTL 預設值為 30 秒,不過這個 30 秒從官方文件上並看不出來,我也是從 Java's DNS cache behaviour 網頁才知道的,官網文件上的說明比較如下圖示:

InetAddress (Java 2 Platform SE 5.0) 明確寫出 networkaddress.cache.ttl 預設值為 -1

InetAddress (Java Platform SE 6) 並沒有寫出networkaddress.cache.ttl 的預設值

 

相關連結