Skip to content

Bun реализует собственный модуль dns и модуль node:dns.

ts
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
import { dns } from "bun";

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

Кэширование DNS в Bun

Bun поддерживает кэширование DNS. Этот кэш делает повторные подключения к тем же хостам быстрее.

На момент написания мы кэшируем до 255 записей максимум на 30 секунд (каждую). Если какие-либо подключения к хосту не удаются мы удаляем запись из кэша. Когда несколько подключений к одному хосту выполняются одновременно DNS-запросы дублируются чтобы избежать множественных запросов к одному хосту.

Этот кэш автоматически используется:

  • bun install
  • fetch()
  • node:http (клиент)
  • Bun.connect
  • node:net
  • node:tls

Когда следует предварительно получать DNS-запись?

Веб-браузеры предоставляют <link rel="dns-prefetch"> для предварительного получения DNS-записей разработчиками. Это полезно когда вы знаете что вам нужно будет подключиться к хосту в ближайшем будущем и хотите избежать начального DNS-запроса.

В Bun вы можете использовать API dns.prefetch для достижения того же эффекта.

ts
import { dns } from "bun";

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

Пример где вы можете захотеть использовать это — драйвер базы данных. Когда ваше приложение впервые запускается вы можете предварительно получить DNS-запись для хоста базы данных чтобы к моменту завершения загрузки всего DNS-запрос для разрешения хоста базы данных мог уже быть завершён.

dns.prefetch

Для предварительного получения DNS-записи вы можете использовать API dns.prefetch. Этот API полезен когда вы знаете что вам скоро нужно будет подключиться к хосту и хотите избежать начального DNS-запроса.

ts
dns.prefetch(hostname: string, port: number): void;

Вот пример:

ts
import { dns } from "bun";

dns.prefetch("bun.com", 443);
//
// ... немного позже ...
await fetch("https://bun.com");

dns.getCacheStats()

Для получения текущей статистики кэша вы можете использовать API dns.getCacheStats. Этот API возвращает объект со следующими свойствами:

ts
{
  cacheHitsCompleted: number; // Завершённые попадания в кэш
  cacheHitsInflight: number; // Попадания в кэш в процессе
  cacheMisses: number; // Промахи кэша
  size: number; // Количество элементов в кэше DNS
  errors: number; // Количество неудачных подключений
  totalCount: number; // Общее количество запросов подключения (включая попадания и промахи кэша)
}

Пример:

ts
import { dns } from "bun";

const stats = dns.getCacheStats();
console.log(stats);
// => { cacheHitsCompleted: 0, cacheHitsInflight: 0, cacheMisses: 0, size: 0, errors: 0, totalCount: 0 }

Настройка TTL кэша DNS

Bun по умолчанию использует 30 секунд для TTL записей кэша DNS. Для изменения вы можете установить переменную окружения $BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS. Например для установки TTL в 5 секунд:

sh
BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS=5 bun run my-script.ts

Почему 30 секунд по умолчанию?

К сожалению системный API внизу (getaddrinfo) не предоставляет способа получить TTL DNS-записи. Это означает что мы должны выбрать число произвольно. Мы выбрали 30 секунд потому что это достаточно долго чтобы увидеть преимущества кэширования и достаточно коротко чтобы вряд ли вызвать проблемы если DNS-запись изменится. Amazon Web Services рекомендует 5 секунд для Java Virtual Machine однако JVM по умолчанию кэширует бессрочно.

Bun от www.bunjs.com.cn