2014年8月9日 星期六

如何避免大量的 DNS Query

使用 Route53 後,發現要上繳的 Query 費用是我實際 access log 的十倍!假如我的主機被打了10萬次,DNS Query 次數則為 100萬次。原來這個問題以前就在發生,只是以前都用免費的 DNS,像是 Linode、Godaddy 或是 Cloudflare,不知道 query 數,所以也不會在意這個問題。

想這個問題想了幾個月,
我懷疑是被惡意攻擊,也發信給 AWS 詢問,還是無解。幾天前突然想到,會不會是現代的瀏覽器都有 DNS prefetch 的功能?於是在 Chrome 的 tab 中,輸入 chrome://net-internals/#dns 來進行測試。
是的,只要是「連結」都會被解析。你的網站會發生這個問題嗎?

可能的情況一:別人連結你

  • 短網址服務
  • Widget 服務
  • 連結會被大量貼在其它網站、新聞或是部落格
工具邦則是有提供 widget 被貼到許多部落客的頁面中,Widget 含有連結,所以會產生了大量的 DNS Query

可能的情況二:子網域太多

工具邦因為是多國語言,在頁面的下方會連出另外 10 種語言版本的連結,像是
  • 繁中版:tw.piliapp.com
  • 英文版:www.piliapp.com
  • 日文版:jp.piliapp.com
  • 總共有 11 國語言..
當 1 位使用者來造訪,會造成 11 個 DNS Query 
而一般的大網站,也都有不少的的子網域在同一個頁面中:
  • 首頁:www.example.com
  • 幫助頁:help.example.com
  • 新聞頁:news.example.com
這類情況都還是蠻常見的,應該都要想辦法來避免。

解決方式零:調整 TTL

調整 TTL 是最基本的,TTL 越長則 query 數越少。這全看你是否需要高度備援。如果你只有一台,當機了也只能關機重灌,那 TTL 設一天都沒問題,也沒其它機器可以切換。如果你需要高度備援,像 Yahoo 是設一分鐘,當然這樣 query 數就超高。工具邦則是設十五分鐘,萬一主要的機器掛了,最多十五分鐘會自動切換到新的機器。

解決方式一:加上 meta

Disable DNS prefetch
<meta http-equiv="x-dns-prefetch-control" content="off">
工具邦是不建議這麼做,一來 dns prefetch 有 prefetch 的好處。建議作法是,不常被使用者點到的連結(像是 footer),可以使用接下來說明的 prefix 作法。

解決方式二:不同子網域加上 prefix

原本是:
  • http://news.example.com/
  • http://help.example.com/

會變成:
  • /link/**http://news.example.com/
  • /link/**http://help.example.com/
當然,要另一隻程式對 /link/ 做 301 導頁

這個跟 Yahoo 首頁的作法一樣,但 Yahoo 是為了統計點擊率,而不是為了解決 DNS 問題。

小結

工具邦採用方法二,目前約減少 60% 的 DNS Query。有什麼新作法或結論,會再持續更新本篇。