> ## Documentation Index
> Fetch the complete documentation index at: https://bun.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# DNS

> 使用 Bun 的 DNS 模块解析 DNS 记录

Bun 实现了自己的 `dns` 模块，以及 `node:dns` 模块。

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
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 }, ...]
```

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
import { dns } from "bun";

dns.prefetch("bun.com", 443);
```

***

## Bun 中的 DNS 缓存

Bun 支持 DNS 缓存。该缓存可以加快对相同主机的重复连接速度。

撰写本文时，我们缓存最多 255 条记录，最大缓存时间为 30 秒（每条记录）。如果连接主机失败，会从缓存中移除该条目。当对同一主机同时发起多个连接时，会去重 DNS 查询，避免对同一主机发起多次请求。

以下操作会自动使用此缓存：

* `bun install`
* `fetch()`
* `node:http`（客户端）
* `Bun.connect`
* `node:net`
* `node:tls`

### 什么时候应该预获取 DNS 记录？

网页浏览器暴露了 [`<link rel="dns-prefetch">`](https://developer.mozilla.org/en-US/docs/Web/Performance/dns-prefetch) 以允许开发者预获取 DNS 记录。当你知道不久将要连接到某个主机，并希望避免首次 DNS 查询延迟时，这非常有用。

在 Bun 中，你可以使用 `dns.prefetch` API 来达到相同效果。

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
import { dns } from "bun";

dns.prefetch("my.database-host.com", 5432);
```

一个可能使用该方式的场景是数据库驱动程序。当你的应用刚启动时，可以预获取数据库主机的 DNS 记录，以便在应用加载完成时，数据库主机的 DNS 查询已经完成。

### `dns.prefetch`

<Warning>此 API 处于实验阶段，将来可能会发生变化。</Warning>

要预获取 DNS 记录，可以使用 `dns.prefetch` API。当你知道很快需要连接某个主机，想避免首次 DNS 查询时，该 API 很有用。

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
dns.prefetch(hostname: string, port: number): void;
```

示例：

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
import { dns } from "bun";

dns.prefetch("bun.com", 443);
//
// ... 过一段时间 ...
await fetch("https://bun.com");
```

### `dns.getCacheStats()`

<Warning>此 API 处于实验阶段，将来可能会发生变化。</Warning>

要获取当前缓存状态，可以使用 `dns.getCacheStats` API。此 API 返回一个包含以下属性的对象：

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
{
  cacheHitsCompleted: number; // 已完成的缓存命中次数
  cacheHitsInflight: number;  // 进行中的缓存命中次数
  cacheMisses: number;        // 缓存未命中次数
  size: number;               // DNS 缓存条目数
  errors: number;             // 连接失败次数
  totalCount: number;         // 总连接请求次数（包含缓存命中和未命中）
}
```

示例：

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
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 秒：

```sh theme={"theme":{"light":"github-light","dark":"dracula"}}
BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS=5 bun run my-script.ts
```

#### 为什么默认是 30 秒？

遗憾的是，底层使用的系统 API（`getaddrinfo`）不提供获取 DNS 记录 TTL 的方式。这意味着我们必须随机设定一个数值。我们选用 30 秒，因为它足够长以体现缓存的效果，也足够短以避免 DNS 记录变更时引发问题。[亚马逊云服务建议 Java 虚拟机设置为 5 秒](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/jvm-ttl-dns.html)，但 JVM 默认情况下缓存时间无限。
