У меня есть ряд функций Node, работающих на AWS Lambda. Эти функции использовали среду выполнения Node 8, но AWS отправил уведомление об окончании срока службы, в котором говорилось, что функции должны быть обновлены до последней версии LTS. После этого я обновил одну из своих функций для использования узла 12. После небольшого периода работы я начинаю видеть тонну ошибок connection terminated unexpectedly
при запросах к базе данных.
Вот ошибки что я вижу:
- Неожиданная ошибка
connection terminated
- И
Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
- похоже, это происходит при первом или втором вызове после того, как соединение прервано неожиданно.
Я использую Knex. js для запросов к базе данных. Я использовал более старую версию knex
и node-postgres
и недавно обновил ее, чтобы посмотреть, решит ли она проблему, но не повезло. Вот версии knex
и node-postgres
, которые я сейчас использую:
"knex": "^0.20.8"
"pg": "^7.17.1"
Единственное изменение, которое я сделал в этой конкретной функции, - это обновление до Node 12. Я также попробовал Node 10, но та же проблема сохраняется. К сожалению, AWS не позволит мне перейти на Node 8, чтобы убедиться, что это действительно проблема. Ни одна из моих других функций, работающих на узле 8, не сталкивалась с этой проблемой.
Я исследовал knex
, node-postgres
и tarn.js
(библиотека пула соединений Knex), чтобы увидеть, есть ли связанные проблемы или решения выскочил, но пока мне не повезло.
ОБНОВЛЕНИЕ:
Пример обработчика. Обратите внимание, что это происходит на многих разных Lambdas, все работают под узлом 12.
require('../../helpers/knex')
const { Rollbar } = require('@scoutforpets/utils')
const { Email } = require('@scoutforpets/notifications')
const { transaction: tx } = require('objection')
const Invoice = require('../../models/invoice')
// configure rollbar for error logging
const rollbar = Rollbar.configureRollbar(process.env.ROLLBAR_TOKEN)
/**
*
* @param {*} event
*/
async function handler (event) {
const { invoice } = event
const { id: invoiceId } = invoice
try {
return tx(Invoice, async Invoice => {
// send the receipt
await Email.Customer.paymentReceipt(invoiceId, true)
// convert JSON to model
const i = Invoice.fromJson(invoice)
// mark the invoice as having been sent
await i.markAsSent()
})
} catch (err) {
return err
}
}
module.exports.handler = rollbar.lambdaHandler(handler)