一段話先講明白
瀏覽器輸入 google.com 到拿到 IP, 平均 15-150 毫秒。這段時間發生了 4 層快取查詢 + 最多 3 次跨網詢問: 瀏覽器 cache → 系統 stub cache → 路由器 cache → ISP 遞迴 resolver cache → 詢問根 (.) → 詢問 TLD (.com) → 詢問權威 (ns.google.com) → 拿到 A 記錄。每層 cache 命中越早越快 — 但快取有 TTL 限制, 過期了得重新走一遍。下面一步一步拆。
一、完整 8 步流程圖
┌─────────────────────────────────────────────────────────────┐
│ 瀏覽器 (Chrome / Firefox) 輸入 google.com │
└────────────────┬────────────────────────────────────────────┘
│ ① 瀏覽器 DNS cache (Chrome ~60s)
↓ miss
┌─────────────────────────────────────────────────────────────┐
│ 作業系統 stub resolver + 系統 DNS 快取 │
└────────────────┬────────────────────────────────────────────┘
│ ② 系統快取 miss → 發 UDP 查詢到路由器
↓
┌─────────────────────────────────────────────────────────────┐
│ 家用路由器 DNS 轉發 + 路由器 cache │
└────────────────┬────────────────────────────────────────────┘
│ ③ 路由器 cache miss → 轉發到 ISP 遞迴 resolver
↓
┌─────────────────────────────────────────────────────────────┐
│ ISP / 公共遞迴 (1.1.1.1 / 8.8.8.8 / 223.5.5.5) │
│ cache 命中: 直接返回, 整個過程 1-5ms │
│ cache miss: 進入下面"完整查詢"流程 │
└────────────────┬────────────────────────────────────────────┘
│ ④ 問根 ns "google.com 在哪? "
↓
13 組根域名伺服器 (a~m.root-servers.net)
│ ⑤ 回 "我不知道, 問 .com 的 NS: a.gtld-servers.net"
↓
.com TLD 權威伺服器 (Verisign)
│ ⑥ 回 "我也不全, 問 google.com 的 NS: ns1.google.com"
↓
google.com 權威伺服器 (Google 自己運營)
│ ⑦ 回 "google.com 的 A 記錄 = 142.250.x.x"
↓
┌─────────────────────────────────────────────────────────────┐
│ ⑧ 遞迴 resolver 把答案快取 (按 TTL), 返回給客戶端 │
│ 沿途各層 cache 也存一份 │
└─────────────────────────────────────────────────────────────┘關鍵洞察: 真實場景裡幾乎從不走完整 8 步。大網站 IP 幾乎永遠在遞迴 resolver cache 裡, 所以普通使用者只走到第 ④ 步就返回。只有冷門 / 長期未訪問 / TTL 過期 / 新註冊域名 才走完整流程。
二、5 層 DNS 快取詳解
DNS 這套系統在 1983 年設計時就考慮到了一個事實: 查詢比改動多 10 萬倍。所以處處是快取, 每層都按 TTL (Time To Live) 快取一段時間。
| 層 | 位置 | 典型 TTL | 怎麼查 / 清 |
|---|---|---|---|
| ① 瀏覽器 | Chrome / Firefox 程序內 | 60 秒 (Chrome) | 查 / 清 chrome://net-internals/#dns |
| ② 作業系統 stub | Windows DNS Client / macOS mDNSResponder / systemd-resolved | 跟 record TTL 一致 | Windows: ipconfig /displaydns 看, ipconfig /flushdns 清 |
| ③ 家用路由器 | 路由器內建 DNS forwarder | 看路由器實現 | 路由器重啟清 / 後臺手動清 |
| ④ ISP / 公共遞迴 | 1.1.1.1 / 8.8.8.8 / 223.5.5.5 | 跟 record TTL 一致 | 使用者清不了, 等 TTL 過期 |
| ⑤ 權威伺服器 | 域名所有者的 NS | 不快取, 是資料來源頭 | — |
三、遞迴查詢 vs 迭代查詢 — 關鍵概念
3.1 遞迴 (Recursive)
客戶端 (瀏覽器 / OS stub) 對 ISP 遞迴 resolver 說: "你幫我把 google.com 的 IP 找出來, 我不管中間過程"。遞迴 resolver 必須完成整個查詢, 把最終結果返回。
3.2 迭代 (Iterative)
遞迴 resolver 跟根 / TLD / 權威伺服器對話時是迭代 — 我問根, 根說"問 .com", 我再去問 .com, .com 說"問 google", 我再去問 google。每一步只跨一層, 不是"我問根, 根幫我搞定一切"。
客戶端 ↔ 遞迴 resolver = 遞迴四、自己實測一下 — dig +trace
dig +trace 會強制做完整迭代查詢, 顯示每一步:
$ dig +trace cleanip.io
; <<>> DiG 9.10.6 <<>> +trace cleanip.io
;; global options: +cmd
; ① 第 1 跳 — 問根 (.)
. 518400 IN NS a.root-servers.net.
. 518400 IN NS b.root-servers.net.
... (13 個根 NS)
;; Received 525 bytes from 127.0.0.53#53 in 5 ms
; ② 第 2 跳 — 問 .io TLD
io. 172800 IN NS a0.nic.io.
io. 172800 IN NS b0.nic.io.
... (.io 的 4 個 NS)
;; Received 822 bytes from 198.41.0.4#53(a.root-servers.net) in 121 ms
; ③ 第 3 跳 — 問 cleanip.io 的權威
cleanip.io. 86400 IN NS nolan.ns.cloudflare.com.
cleanip.io. 86400 IN NS treasure.ns.cloudflare.com.
;; Received 109 bytes from 156.154.150.6#53(a0.nic.io) in 53 ms
; ④ 終於拿到答案
cleanip.io. 300 IN A 104.21.x.x
cleanip.io. 300 IN A 172.67.x.x
cleanip.io. 86400 IN NS nolan.ns.cloudflare.com.
cleanip.io. 86400 IN NS treasure.ns.cloudflare.com.
;; Received 154 bytes from 173.245.59.108#53(nolan.ns.cloudflare.com) in 12 ms解讀:
- 整個流程 5 + 121 + 53 + 12 = 191 ms, 第一次冷查詢確實慢
- 但下一秒同個域名再查只需要 1-2 ms, 因為 ISP 遞迴 cache 已經有了 (TTL 300 秒)
104.21.x.x / 172.67.x.x是 Cloudflare CDN, 我們站點真實源站 IP 被 CDN 隱藏
五、TTL 詳解 — 快取到底緩多久
TTL (Time To Live) 是權威伺服器告訴所有遞迴 resolver "你最多快取這麼久"的欄位, 單位秒。
| 典型 TTL | 含義 | 用在哪 |
|---|---|---|
| 60 (1 分鐘) | 極短, 適合頻繁切 IP 的服務 | 故障切換 / A/B 測試 |
| 300 (5 分鐘) | 短, CDN 常用 | Cloudflare 預設 |
| 3600 (1 小時) | 中等 | 普通網站 |
| 86400 (1 天) | 長 | NS 記錄 / 不常變的 A 記錄 |
| 172800 (2 天) | TLD NS 標配 | .com / .io 等 NS 記錄 |
| 518400 (6 天) | 根 NS 標配 | 13 根伺服器的 NS 記錄 |
注意: TTL 是"最大快取時間", 各級 resolver 實際可以提前清快取, 但不能延長。所以即便你權威 TTL 是 1 小時, 實際有的 resolver 可能 10 分鐘就重新查。
陷阱: 換 IP 前要先把 TTL 調短 (1-5 分鐘), 等老 TTL 全過期後再切, 否則部分使用者會持續 1+ 小時訪問舊 IP。
六、DNS 記錄類型速查
| 類型 | 含義 | 例子 |
|---|---|---|
| A | IPv4 地址 | cleanip.io → 104.21.x.x |
| AAAA | IPv6 地址 | cleanip.io → 2606:4700::6810:x |
| CNAME | 別名 (跳到另一個域名) | www.cleanip.io → cleanip.io |
| NS | 域名的權威 NS | cleanip.io → nolan.ns.cloudflare.com |
| MX | 郵件伺服器 | cleanip.io → mx1.cleanip.io (10) |
| TXT | 任意文本 (SPF / DKIM / 驗證) | SPF / Google verification |
| SOA | 區域起始, 包含主 NS / 郵箱 / 序列號 | 每個 zone 一條 |
| PTR | 反查: IP → 主機名 | 8.8.8.8 → dns.google |
| CAA | 誰能給我籤 SSL 證書 | cleanip.io → letsencrypt.org |
| SRV | 服務記錄 (含埠) | SIP / XMPP / Matrix |
七、DNS 最佳化 — 怎麼讓解析更快
7.1 選近的遞迴 resolver
中國大陸: 223.5.5.5 (阿里) / 119.29.29.29 (DNSPod) — 國內站點解析最快。海外: 1.1.1.1 (Cloudflare, anycast 節點覆蓋最廣) / 8.8.8.8 (Google)。詳見公共 DNS 大全.
7.2 開 DoH (DNS-over-HTTPS)
走 HTTPS 加密 DNS 查詢, 防 ISP 看 / 改 (防 NXDOMAIN 劫持)。Chrome / Firefox / Edge 都支援, 設定裡開即可。
7.3 提前預熱 (DNS Prefetch)
網站 <head> 里加 <link rel="dns-prefetch" href="//api.example.com">, 瀏覽器空閒時提前解析, 等真訪問就是 cache hit。
7.4 用 CDN + Anycast NS
權威 NS 用 Anycast (Cloudflare / Route 53), 全球使用者就近問到, 第 ③ 步耗時從 100ms 降到 10ms。
7.5 合理設 TTL
不會變的記錄 (NS / MX) TTL 設長 (1-7 天); 可能切換的 A 記錄設短 (5-60 分鐘)。
八、常見問題
8.1 改了 DNS 但沒生效 — 為啥
先想想: 當前 TTL 是多少? 改 DNS 後, 老 TTL 沒過期之前, 所有遞迴 resolver 還會返回舊 IP。"全球生效" 一般要等 TTL × 2 時間 (考慮各 resolver 不同步)。
- 客戶端:
ipconfig /flushdns(Windows) /sudo killall -HUP mDNSResponder(macOS) - 等公共遞迴 cache 過期: 1.1.1.1 / 8.8.8.8 可以用各自的 "purge" 工具手動清
8.2 部分使用者能訪問, 部分不能 — DNS 汙染
中國大陸訪問境外網站常見 — GFW DNS 注入 / ISP 劫持。換用 DoH (瀏覽器加密 DNS) 可繞過大部分 DNS 汙染。
8.3 域名註冊後多久能用
註冊後, TLD 註冊局把你的 NS 記錄推送到 .com / .net 等頂級權威 — 一般 15 分鐘到 24 小時。.cn / .com.cn 可能需要 ICP 備案才能在中國大陸解析。
延伸閱讀
- 為什麼只有 13 組根域名伺服器DNS 流程的最頂層 ④ 步
- 全球公共 DNS 大全選哪個 resolver 解析最快
- RFC 1035 — DNS 協議原文
- RFC 8484 — DoH (DNS-over-HTTPS)