導覽列

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。有什麼新作法或結論,會再持續更新本篇。