Bun 實現了自己的 dns 模塊,以及 node:dns 模塊。
import * as dns from "node:dns";
const addrs = await dns.promises.resolve4("bun.com", { ttl: true });
console.log(addrs);
// => [{ address: "172.67.161.226", family: 4, ttl: 0 }, ...]import { dns } from "bun";
dns.prefetch("bun.com", 443);Bun 中的 DNS 緩存
Bun 支持 DNS 緩存。此緩存使與相同主機的重復連接更快。
在撰寫本文時,我們最多緩存 255 個條目,每個條目最長 30 秒。如果與主機的任何連接失敗,我們會從緩存中刪除該條目。當同時與同一主機建立多個連接時,DNS 查找會去重,以避免為同一主機發出多個請求。
此緩存由以下自動使用:
bun installfetch()node:http(客戶端)Bun.connectnode:netnode:tls
何時應該預取 DNS 條目?
Web 瀏覽器公開 <link rel="dns-prefetch"> 允許開發者預取 DNS 條目。當你知道將來需要連接到主機並希望避免初始 DNS 查找時,這很有用。
在 Bun 中,你可以使用 dns.prefetch API 實現相同的效果。
import { dns } from "bun";
dns.prefetch("my.database-host.com", 5432);一個你可能想使用此功能的示例是數據庫驅動程序。當你的應用程序首次啟動時,你可以預取數據庫主機的 DNS 條目,以便在完成加載所有內容時,解析數據庫主機的 DNS 查詢可能已經完成。
dns.prefetch
要預取 DNS 條目,你可以使用 dns.prefetch API。當你知道將來需要連接到主機並希望避免初始 DNS 查找時,此 API 很有用。
dns.prefetch(hostname: string, port: number): void;這是一個示例:
import { dns } from "bun";
dns.prefetch("bun.com", 443);
//
// ... 稍後 ...
await fetch("https://bun.com");dns.getCacheStats()
要獲取當前緩存統計信息,你可以使用 dns.getCacheStats API。此 API 返回一個具有以下屬性的對象:
{
cacheHitsCompleted: number; // 已完成的緩存命中
cacheHitsInflight: number; // 進行中的緩存命中
cacheMisses: number; // 緩存未命中
size: number; // DNS 緩存中的項目數
errors: number; // 連接失敗的次數
totalCount: number; // 請求連接的總次數(包括緩存命中和未命中)
}示例:
import { dns } from "bun";
const stats = dns.getCacheStats();
console.log(stats);
// => { cacheHitsCompleted: 0, cacheHitsInflight: 0, cacheMisses: 0, size: 0, errors: 0, totalCount: 0 }配置 DNS 緩存 TTL
Bun 默認 DNS 緩存條目的 TTL 為 30 秒。要更改此設置,可以設置環境變量 $BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS。例如,將 TTL 設置為 5 秒:
BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS=5 bun run my-script.ts為什麼默認是 30 秒?
不幸的是,底層系統 API(getaddrinfo)沒有提供獲取 DNS 條目 TTL 的方法。這意味著我們必須隨意選擇一個數字。我們選擇 30 秒是因為它足夠長以看到緩存的好處,又足夠短,不太可能在 DNS 條目更改時導致問題。Amazon Web Services 建議 Java 虛擬機使用 5 秒,但 JVM 默認無限期緩存。