MongoDB

Node.js и MongoDB: как правильно закрывать client.close

В Node.js client.close() нужно вызывать тогда, когда приложение действительно завершает работу с MongoDB. В одноразовом скрипте закрывайте клиент в finally. В Express-сервере не закрывайте подключение после каждого HTTP-запроса: создайте клиент один раз при старте и закрывайте его при остановке процесса

Пример для скрипта:

import { MongoClient } from "mongodb";

const client = new MongoClient("mongodb://localhost:27017");

try {
  await client.connect();
  const db = client.db("shop");
  const products = await db.collection("products").find().toArray();
  console.log(products);
} finally {
  await client.close();
}

Так соединение закроется даже при ошибке

Express-приложение

Для сервера лучше подключиться один раз:

import express from "express";
import { MongoClient } from "mongodb";

const app = express();
const client = new MongoClient(process.env.MONGODB_URI);

await client.connect();
const db = client.db("shop");

app.get("/products", async (req, res) => {
  const products = await db.collection("products").find().toArray();
  res.json(products);
});

const server = app.listen(3000);

Не делайте так внутри каждого route:

await client.connect();
await client.close();

Это создает лишнюю нагрузку и может замедлить приложение

Graceful shutdown

Закройте MongoDB-клиент при остановке сервера:

async function shutdown() {
  server.close(async () => {
    await client.close();
    process.exit(0);
  });
}

process.on("SIGINT", shutdown);
process.on("SIGTERM", shutdown);

Так приложение перестает принимать новые запросы, останавливает сервер и затем завершает MongoDB-клиент

Когда close точно нужен

client.close() нужен в CLI-скриптах, миграциях, seed-скриптах, тестах и обработчиках завершения процесса. Если код запускается, делает работу и заканчивает выполнение, закрытие обязательно. Иначе Node.js может продолжать висеть из-за открытого подключения

Как понять, что клиент закрывают слишком рано

Типичный симптом — первый запрос работает, а второй падает или снова долго подключается к базе. В логах может быть видно, что приложение создает новый MongoClient при каждом обращении к API. Для Express это сигнал пересмотреть архитектуру: подключение должно жить на уровне приложения, а route должен только брать готовую коллекцию и выполнять запрос

Нормальная схема такая: connect при старте, работа routes, close при остановке процесса. Это проще отлаживать и легче масштабировать

Когда close мешает

Если закрыть клиент после первого запроса Express, следующий route может получить ошибку вроде MongoClient must be connected или начнет заново открывать соединение. Для веб-приложения это неправильный жизненный цикл

Частые ошибки

Закрывают клиент после каждого запроса

Создайте подключение один раз и переиспользуйте db

Не используют finally в скрипте

При ошибке соединение может остаться открытым. В скриптах закрывайте в finally

Не ждут await client.close()

close() асинхронный. Используйте await, чтобы завершение прошло корректно

Создают много MongoClient

Один процесс обычно должен иметь один общий клиент для приложения

Не обрабатывают остановку процесса

Если приложение работает на сервере, добавьте обработчики SIGTERM и SIGINT. Так деплой или остановка контейнера пройдут аккуратнее

Что почитать дальше по MongoDB

Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x