Ошибка «неожиданно прервано соединение» с узлом, Postgres on AWS Lambda - PullRequest
0 голосов
/ 23 января 2020

У меня есть ряд функций Node, работающих на AWS Lambda. Эти функции использовали среду выполнения Node 8, но AWS отправил уведомление об окончании срока службы, в котором говорилось, что функции должны быть обновлены до последней версии LTS. После этого я обновил одну из своих функций для использования узла 12. После небольшого периода работы я начинаю видеть тонну ошибок connection terminated unexpectedly при запросах к базе данных.

Вот ошибки что я вижу:

  1. Неожиданная ошибка connection terminated
  2. И 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)

1 Ответ

0 голосов
/ 24 января 2020

Начиная с node.js 10 aws лямбда, сделайте handler asyn c, поэтому вам придется адаптировать свой код. Документы: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

Среда выполнения передает три аргумента методу-обработчику. Первый аргумент - это объект события, который содержит информацию от вызывающего. Призыватель передает эту информацию в виде JSON -форматированной строки, когда вызывает Invoke, и среда выполнения преобразует ее в объект. Когда служба AWS вызывает вашу функцию, структура события зависит от службы.

Второй аргумент - это объект контекста, который содержит информацию о вызове, функции и среде выполнения. В предыдущем примере функция получает имя потока журнала из объекта контекста и возвращает его вызывающему.

Третий аргумент, обратный вызов, является функцией, которую можно вызывать в non-asyn * 1024. * функции для отправки ответа. Функция обратного вызова принимает два аргумента: Ошибка и ответ. Когда вы вызываете его, Lambda ожидает, пока событие l oop будет пустым, и затем возвращает ответ или ошибку вызывающему. Объект ответа должен быть совместим с JSON .stringify.

Для асинхронных c функций вы возвращаете ответ, ошибку или обещание среде выполнения вместо использования обратного вызова.

exports.handler =  async function(event, context, callback) {
  console.log("EVENT: \n" + JSON.stringify(event, null, 2))
  return context.logStreamName
}

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...