Вопрос или проблема
Я использую knex
для подключения к базе данных и продолжаю сталкиваться с ошибкой, когда достигнуто максимальное количество соединений в пуле, говорится: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?
Моя конфигурация knex выглядит следующим образом;
const knex = require("knex")({
client: "pg",
connection: {
connectionString: process.env.connection_string,
},
pool: {
min: 0,
max: 300,
idleTimeoutMillis: 30000,
createTimeoutMillis: 30000,
acquireTimeoutMillis: 30000
},
}
);
knex: "^3.1.0"
pg: "^8.13.0"
Версия Node: 18.18.2
nvm: 0.38.0
npm: 9.8.1
Что я заметил, так это то, что некоторые из моих соединений пула не закрываются автоматически. Есть ли способ установить тайм-аут для соединений пула, если выполнение занимает больше времени, чем я указал, тогда остановить его и закрыть соединение пула. В конфигурации я установил idleTimeoutMillis
на 30000мс (30 секунд). Но я не думаю, что это работает так, как я хочу. В данный момент у меня около 100 открытых соединений пула, которые открыты почти 2 часа. Я измеряю количество использованных соединений пула с помощью knex.client.pool.numUsed()
. У вас есть какие-нибудь идеи?
Я вижу некоторые обходные пути, такие как;
- Понижение версии node. Я не хочу этого делать!
- Добавление параметра
propagateCreateError
в конфигурацию, что не рекомендуется командой knex!
Ответ или решение
Как установить таймаут для открытых пулов подключений в Knex.js
При работе с библиотекой Knex.js для взаимодействия с базами данных, особенно при использовании пула соединений, важно правильно настраивать параметры конфигурации, чтобы избежать ошибок, связанных с исчерпанием пула соединений. Ваша проблема заключается в ошибке: "Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?", что указывает на возможные проблемы с управлением соединениями.
Настройка параметров пула соединений
На основании предоставленной конфигурации, вы уже указали несколько ключевых параметров пула:
pool: {
min: 0,
max: 300,
idleTimeoutMillis: 30000,
createTimeoutMillis: 30000,
acquireTimeoutMillis: 30000
}
Параметры конфигурации:
min
: Минимальное количество подключений в пуле (в вашем случае 0).max
: Максимальное количество подключений в пуле (в вашем случае 300).idleTimeoutMillis
: Время в миллисекундах, после которого неиспользуемые соединения будут закрыты (30 секунд).createTimeoutMillis
: Время в миллисекундах, выделяемое на создание нового соединения (30 секунд).acquireTimeoutMillis
: Время в миллисекундах, после которого запрос на получение соединения будет завершен с ошибкой (30 секунд).
Проблема с не закрытыми соединениями
Ваш наблюдение о 100 открытых подключениях, которые остаются открытыми на протяжении 2 часов, указывает на возможные недостатки в логике вашего приложения или неправильную обработку транзакций и асинхронных операций. Вот что вы можете сделать:
Рекомендации:
-
Проверка использования транзакций:
Убедитесь, что вы используете метод.transacting(trx)
при работе с транзакциями. Это очень важно, поскольку он позволит обеспечить правильное управление соединениями.Пример использования транзакции:
await knex.transaction(async (trx) => { await trx('table_name').insert(data); });
-
Увеличение параметров тайм-аута:
Если ваша логика требует больше времени для обработки запросов, рассмотрите возможность увеличенияacquireTimeoutMillis
, чтобы избежать ошибок захвата соединений. -
Мониторинг используемых соединений:
Используйтеknex.client.pool.numUsed()
для мониторинга числа активно используемых соединений. Это позволит вам видеть, насколько эффективно используются ваши соединения и помогает выявить возможные утечки. -
Закрытие соединений вручную:
В случаях, когда соединения не закрываются автоматически, вы можете добавить логику для закрытия соединений вручную после выполнения операций. Это может быть реализовано черезknex.destroy()
в конце выполнения запросов:process.on('exit', async () => { await knex.destroy(); });
-
Использование Microsoft Edge Case Handlers:
Рассмотрите возможность добавления обработчиков исключений для управления непредвиденными ситуациями, чтобы убедиться, что соединения закрываются в любых случаях. -
Настройка
propagateCreateError
:
Хотя команде Knex не рекомендуется использовать этот параметр, в некоторых случаях он может помочь выявить, в чем проблема. Обдумайте, готов ли вы следовать этому пути.
Заключение
Корректная настройка параметров пула соединений в Knex.js — это залог стабильной работы вашего приложения. Проведите ревизию своей логики работы с соединениями, убедитесь в использовании транзакций и механизмах закрытия соединений. Оптимизация этих аспектов поможет вам избежать ошибок и улучшить производительность вашей базы данных. Если проблема будет продолжаться, возможно, стоит обратиться к сообществу Knex или изучить документацию для решения более сложных задач.