代理閘道切換時如何排查陳舊 DNS 快取

代理閘道網域已指向新位址,執行中的工作卻仍可能使用舊路徑。原因通常不是單一快取,而是多層狀態疊加:權威 DNS、遞迴解析器、作業系統、應用程式執行環境、HTTP 用戶端及已建立的連線池,都可能依不同週期保留資訊。
本指南面向以住宅代理、輪替代理進行合規資料蒐集、市場研究與廣告驗證的維運團隊。目標是找出哪一層保留舊狀態,證明新閘道可正常運作,並確保切換期間不會出現不安全的直接連線回退。
先區分三類故障
不要把所有解析錯誤都稱為「DNS 陳舊」:
- 正向快取陳舊:仍回傳或重用舊的 A、AAAA 位址。
- 負向快取持續:網域恢復後,先前 NXDOMAIN 或無資料結果仍被快取。
- 連線重用:DNS 已更新,但用戶端繼續使用連往舊位址的 TCP、TLS 或 HTTP/2 連線。
三種問題需要不同處理。一次重啟全部工作程序可能掩蓋原因,也可能造成重試尖峰。
畫出全部解析與重用層
針對代理閘道網域記錄:
- 權威 A、AAAA、CNAME 與 TTL;
- 正式工作所用的遞迴解析器;
- 容器、虛擬機器或主機的解析設定;
- 執行環境使用的解析 API;
- 用戶端函式庫的 DNS 快取政策;
- 連線池閒置時間與最大壽命;
- 代理工作階段壽命與黏著規則;
- 負載平衡器或閘道健康行為。
Node.js 的 dns.lookup() 通常使用作業系統解析能力,而 dns.resolve*() 會執行網路 DNS 查詢,兩者設定路徑並不相同。因此,診斷程式和實際應用若使用不同 API,結果可能不一致。
libcurl 亦維護記憶體 DNS 快取。官方文件說明預設快取時間為 60 秒,並不直接採用 DNS 記錄 TTL。現行版本對權威「網域不存在」與暫時、本機解析失敗的快取方式也不同。解讀測試前應記錄用戶端版本。
建立切換前基準
在每個正式區域執行小規模授權金絲雀,只保存去識別化證據:
timestamp
workload_region
resolver_alias
gateway_hostname_alias
answer_family
answer_set_hash
dns_lookup_ms
new_connection_or_reuse
connected_gateway_alias
proxy_auth_result
observed_exit_market
request_result
不得記錄代理密碼、權杖、Cookie、客戶識別資訊或完整敏感目的 URL。
A 與 AAAA 必須分別驗證。IPv4 成功不代表 IPv6 路徑正常,位址順序改變也可能影響執行環境優先嘗試的位址族。
分階段執行閘道切換
1. 提前降低權威 TTL
預留足夠時間,讓舊 TTL 在常見解析器中到期,並從多個正式區域確認新值。與位址同時降低 TTL,無法縮短已依舊值快取的記錄。
2. 先加入新位址,再移除舊位址
架構允許時,讓新舊健康閘道短期重疊。全面轉移前驗證新閘道的代理驗證、TLS 主機名稱、允許方法、頻寬、出口選擇與日誌。
3. 不更動 DNS,單獨固定一次金絲雀連線
使用安全的用戶端機制,只在單次金絲雀中把閘道網域和連接埠綁定至新位址。必須保留網域供 TLS 與代理驗證使用,不能在正式設定中直接改成裸 IP。固定測試可將閘道可用性與解析器行為分開。
4. 比較冷程序與熱程序
以同一請求比較:
- 沒有應用快取的新程序;
- 已有 DNS 快取的熱程序;
- 金絲雀中停用連線重用的熱程序;
- 正常正式連線池。
若只有正式連線池仍連往舊位址,應先檢查連線壽命,不要盲目刷新 DNS。
5. 證據收斂後才移除舊位址
要求所有必要區域都取得預期位址集合、新連線成功、代理出口正確、應用結果穩定,並保留明確回復時段。
單獨診斷負向快取
NXDOMAIN 必須有自己的時間線。RFC 2308 規範使用區域 SOA 資訊進行負向快取。權威解析曾回傳網域不存在時,即使記錄立刻恢復,部分用戶端也可能要等負向快取到期後才看得到。
處理負向快取事件時:
- 確認權威結果為 NXDOMAIN、無資料、逾時或本機失敗;
- 檢查決定負向快取壽命的 SOA 值;
- 查詢正式遞迴解析器,而非只用公共診斷解析器;
- 比較全新解析路徑與受影響應用;
- 負向記錄有效期間避免緊密重試;
- 在預期到期時間後驗證恢復。
不能把每次查詢失敗都轉成位址輪替。暫時解析器故障與權威網域不存在是不同營運訊號。
讓代理維持失敗關閉
DNS 故障時,強制代理工作不得移除代理設定或直接連線目的端。驗證:
- 代理網域無法解析時,工作停止或進入有上限的佇列;
- 舊位址不能繞過代理驗證;
- 備援閘道經明確核准與獨立測試;
- 恢復期間
NO_PROXY範圍不會擴大; - 重試包含指數退避、抖動與總預算;
- 排隊工作有過期時間與花費上限。
首試成功率與最終成功率應分開記錄。最終 100% 成功仍可能掩蓋數分鐘錯誤路由與大量重試。
決策表
| 觀察 | 可能層級 | 下一步 |
|---|---|---|
| 遞迴查詢仍回傳舊位址 | 上游快取 | 等待有效 TTL 或修正權威資料 |
| 遞迴結果已新,應用結果仍舊 | 系統或執行環境快取 | 檢查解析 API 與程序快取 |
| 查詢已新,連線仍到舊位址 | 連線池 | 受控排空或縮短連線壽命 |
| A 已更新但 AAAA 仍舊 | 位址族路徑 | 分別測試 IPv4 與 IPv6 |
| 網域恢復後仍失敗 | 負向快取 | 核對 NXDOMAIN 壽命與到期時間 |
| 代理網域失敗後流量直連 | 政策缺陷 | 停止工作並修復失敗關閉路由 |
驗收清單
- [ ] TLS 與驗證持續使用同一正確閘道網域。
- [ ] 新舊 A 與 AAAA 集合已記錄。
- [ ] 計畫時段後權威與遞迴結果一致。
- [ ] 冷程序與熱程序均已測試。
- [ ] 可區分新建與重用連線。
- [ ] 新閘道通過驗證與出口區域檢查。
- [ ] 直接連線回退已阻擋。
- [ ] 重試與佇列預算可防止恢復風暴。
- [ ] 日誌不含憑證或敏感 URL。
- [ ] 所有區域證據收斂後才移除舊閘道。
- [ ] 回復標準與負責人已記錄。
相關控制可參考 98IP 的代理故障切換復原演練、SOCKS5 遠端 DNS 測試與代理服務 SLA 驗證手冊。
常見問題
應用 DNS 快取必須完全遵循記錄 TTL 嗎?
不一定。用戶端函式庫與作業系統可能有獨立快取政策。應記錄正式技術堆疊的實際行為,不能假設權威 TTL 控制所有層。
刷新 DNS 就足夠嗎?
不足。DNS 更新後,既有連線仍可繼續使用舊閘道。先在金絲雀停用連線重用;若原因確為重用,再逐步排空連線池。
是否應將 DNS 快取設為零?
通常不應作為通用修正。停用快取會增加解析器負載與延遲。應選擇符合切換目標的有限快取與連線壽命,並在負載下驗證。
可以把代理網域換成裸 IP 嗎?
這可能破壞 TLS 主機名稱驗證、閘道路由與維運彈性。診斷時使用受控固定機制,同時保留預期網域。
合規說明
僅將代理用於合法、已授權的工作。遵守目的端條款、robots 指示、存取控制、隱私義務與速率限制。不得利用 DNS 變更、備援閘道或重試規避存取決定。只保留可靠性與合規所需的診斷資料。
內部研究依據:curl 專案的 DNS 快取時間文件、Node.js DNS 文件、IETF RFC 2308 負向 DNS 快取規範。來源 URL 僅保存在內部營運記錄中。