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 默认无限期缓存。