為什麼 Chromium 記憶體 DNS 超過一分鐘?
我使用 Chromium 並且在我期望的時間內沒有記憶體 DNS 的問題。以 example.com 域為例。根據 DNS 設置,此域應再記憶體 26151 秒:
$ dig example.com ;; ANSWER SECTION: example.com. 26151 IN A 93.184.216.34
但是,當我在 Chromium 中打開 example.com 並打開 chrome://net-internals/#dns 時,IP 會在一分鐘內被遺忘!
為什麼 Chromium 不遵守域的 DNS 設置的 TTL?如何強制它記憶體 DNS 數據直到它們過期?
Chromium/Chrome 確實不會記憶體 DNS 請求超過一分鐘。
有趣的是,來自bugs-chromium -Issue 164026 - DNS TTL not honored from Apr 21 2011
系統中唯一的 DNS 記憶體是 chrome,它不支持 TTL。我們需要修復 chrome 和/或添加一個可以正確處理 TTL 的中間記憶體。
在 2012 年 12 月 4 日的票中回答:
HostCache 目前假定所有正面結果的 TTL=60 秒。對於非同步 DNS 解析器,我們計劃使用 TTL=max(60s, server_reported_ttl),即至少 60s。基本原理是提高記憶體性能。(當 CDN NS 提供 TTL=10-20s,並且需要 30s+ 來獲取所有子資源時,我們經常需要在一個頁面載入期間重新查詢相同的主機名。)
門票於 2013 年 10 月 10 日截止:
CrOS 上的 Chrome 使用非同步 DNS 解析器,它支持 TTL = max(60s, > server_reported_ttl)
我將其作為 WontFix 關閉(已過時/按預期工作)。
多年來,這一直是一個已知問題。他們的內部 DNS 解析器會忽略 DNS 記錄的 TTL,並且只記憶體 DNS 請求 1 分鐘。
使用者多年來一直在請求一項改變這種預設行為的功能,而Google從未創建過這樣的功能。
過去,您可以在 中禁用內部 DNS 解析器
chrome://flags
,而現在該功能不再公開。綜上所述,它是一個特性,例如它是通過設計實現的。
(我最初寫道它永遠不會被改變,這顯然不是真的。一個真正有決心的人可以重新編譯 Chromium 或破解 Chrome 二進製文件。)。
因此,作為附錄:有大量書面證據表明Google工程師不打算在 Chrome/ium 中接收到的 DNS 答案中尊重預設 TTL。
與記憶體肯定響應一樣,解析器限制記憶體否定響應的時間是明智的……
雖然暗示解析器可能/應該對記憶體 DNS 答案施加最大限制,但 Google Chrome 上的 1 分鐘限制可能太低了。
PS 實際上,在檢索 Chrome 統計資訊以回答這個問題時,我發現了多年來一直困擾我的問題的答案:Chrome:帶有隨機 DNS 名稱的 DNS 請求:惡意軟體?
PPS 從下面的程式碼中,很明顯否定答案沒有被記憶體(TTL=0)。
來自https://chromium.googlesource.com/chromium/src/net/dns/host_resolver_impl.cc
99 // Default TTL for successful resolutions with ProcTask. 100 const unsigned kCacheEntryTTLSeconds = 60; 101 102 // Default TTL for unsuccessful resolutions with ProcTask. 103 const unsigned kNegativeCacheEntryTTLSeconds = 0; 104 105 // Minimum TTL for successful resolutions with DnsTask. 106 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds; 1518 // Called by ProcTask when it completes. 1519 void OnProcTaskComplete(base::TimeTicks start_time, 1520 int net_error, 1521 const AddressList& addr_list) { 1522 DCHECK(is_proc_running()); 1523 1524 if (dns_task_error_ != OK) { 1525 base::TimeDelta duration = base::TimeTicks::Now() - start_time; 1526 if (net_error == OK) { 1527 UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.FallbackSuccess", duration); 1528 if ((dns_task_error_ == ERR_NAME_NOT_RESOLVED) && 1529 ResemblesNetBIOSName(key_.hostname)) { 1530 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_SUSPECT_NETBIOS); 1531 } else { 1532 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_PROC_SUCCESS); 1533 } 1534 base::UmaHistogramSparse("Net.DNS.DnsTask.Errors", 1535 std::abs(dns_task_error_)); 1536 resolver_->OnDnsTaskResolve(dns_task_error_); 1537 } else { 1538 UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.FallbackFail", duration); 1539 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL); 1540 } 1541 } 1542 1543 if (ContainsIcannNameCollisionIp(addr_list)) 1544 net_error = ERR_ICANN_NAME_COLLISION; 1545 1546 base::TimeDelta ttl = # always 0 seconds 1547 base::TimeDelta::FromSeconds(kNegativeCacheEntryTTLSeconds); 1548 if (net_error == OK) # always 60 seconds 1549 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); 1550 1551 // Source unknown because the system resolver could have gotten it from a 1552 // hosts file, its own cache, a DNS lookup or somewhere else. 1553 // Don't store the |ttl| in cache since it's not obtained from the server. 1554 CompleteRequests( 1555 MakeCacheEntry(net_error, addr_list, HostCache::Entry::SOURCE_UNKNOWN), 1556 ttl); 1557 }