简体   繁体   English

AWS Lambda 上的节点、Postgres 出现“连接意外终止”错误

[英]"connection terminated unexpectedly" error with Node, Postgres on AWS Lambda

I have a number of Node functions running on AWS Lambda.我在 AWS Lambda 上运行了许多节点功能。 These functions have been using the Node 8 runtime but AWS sent out an end-of-life notice saying that functions should be upgraded to the latest LTS.这些函数一直在使用 Node 8 运行时,但 AWS 发出了生命周期终止通知,说函数应该升级到最新的 LTS。 With that, I upgraded one on my functions to use Node 12. After being in production for a bit, I'm starting to see a ton of connection terminated unexpectedly errors when querying the database.有了这个,我在我的功能上升级了一个以使用 Node 12。在生产一段时间后,我开始看到在查询数据库时出现大量connection terminated unexpectedly错误。

Here are the errors that I'm seeing:以下是我看到的错误:

  1. The connection terminated unexpectedly error connection terminated错误
  2. And Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed - this seems to happen on the 1st or second invocation after seeing the connection terminated unexpectedly error.并且Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed - 这似乎发生在看到连接意外终止错误后的第一次或第二次调用时。

I'm using Knex.js for querying the database.我正在使用 Knex.js 来查询数据库。 I was running older version of knex and node-postgres and recently upgraded to see if it would resolve the issue, but no luck.我正在运行旧版本的knexnode-postgres并且最近升级以查看它是否可以解决问题,但没有运气。 Here are the versions of knex and node-postgres that I'm currently running:以下是我当前正在运行的knexnode-postgres版本:

"knex": "^0.20.8" "pg": "^7.17.1"

The only change I've made to this particular function is the upgrade to Node 12. I've also tried Node 10, but the same issue persists.我对这个特定的 function 所做的唯一更改是升级到节点 12。我也尝试过节点 10,但同样的问题仍然存在。 Unfortunately, AWS won't let me downgrade to Node 8 to verify that it is indeed an issue.不幸的是,AWS 不会让我降级到 Node 8 来验证它确实是一个问题。 None of my other functions running on Node 8 are experiencing this issue.我在节点 8 上运行的其他功能都没有遇到这个问题。

I've researched knex , node-postgres and tarn.js (the Knex connection pooling library) to see if any related issues or solutions popped up, but so far, I haven't had any luck.我研究knexnode-postgrestarn.js (Knex 连接池库),看看是否出现了任何相关的问题或解决方案,但到目前为止,我还没有运气。

UPDATE:更新:

Example of a handler.处理程序的示例。 Note that this is happening on many different Lambdas, all running Node 12.请注意,这发生在许多不同的 Lambda 上,它们都运行 Node 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)

I have a number of Node functions running on AWS Lambda.我在 AWS Lambda 上运行了许多 Node 函数。 These functions have been using the Node 8 runtime but AWS sent out an end-of-life notice saying that functions should be upgraded to the latest LTS.这些函数一直在使用 Node 8 运行时,但 AWS 发出了生命周期终止通知,指出函数应升级到最新的 LTS。 With that, I upgraded one on my functions to use Node 12. After being in production for a bit, I'm starting to see a ton of connection terminated unexpectedly errors when querying the database.有了这个,我升级了我的函数以使用 Node 12。在生产一段时间后,我开始看到大量的connection terminated unexpectedly在查询数据库时connection terminated unexpectedly错误。

Here are the errors that I'm seeing:以下是我看到的错误:

  1. The connection terminated unexpectedly error connection terminated意外connection terminated错误
  2. And Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed - this seems to happen on the 1st or second invocation after seeing the connection terminated unexpectedly error.Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed - 这似乎发生在第一次或第二次调用后看到连接意外终止错误。

I'm using Knex.js for querying the database.我正在使用 Knex.js 查询数据库。 I was running older version of knex and node-postgres and recently upgraded to see if it would resolve the issue, but no luck.我正在运行旧版本的knexnode-postgres并且最近升级以查看它是否可以解决问题,但没有运气。 Here are the versions of knex and node-postgres that I'm currently running:以下是我目前正在运行的knexnode-postgres版本:

"knex": "^0.20.8" "pg": "^7.17.1"

The only change I've made to this particular function is the upgrade to Node 12. I've also tried Node 10, but the same issue persists.我对这个特定功能所做的唯一更改是升级到 Node 12。我也尝试过 Node 10,但同样的问题仍然存在。 Unfortunately, AWS won't let me downgrade to Node 8 to verify that it is indeed an issue.不幸的是,AWS 不允许我降级到 Node 8 以验证它确实是一个问题。 None of my other functions running on Node 8 are experiencing this issue.我在 Node 8 上运行的其他函数都没有遇到这个问题。

I've researched knex , node-postgres and tarn.js (the Knex connection pooling library) to see if any related issues or solutions popped up, but so far, I haven't had any luck.我研究了knexnode-postgrestarn.js (Knex 连接池库),看看是否有任何相关问题或解决方案出现,但到目前为止,我还没有任何运气。

UPDATE:更新:

Example of a handler.处理程序的示例。 Note that this is happening on many different Lambdas, all running Node 12.请注意,这发生在许多不同的 Lambda 上,所有这些 Lambda 都运行 Node 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)

I think you need to set the right connection pooling config.我认为您需要设置正确的连接池配置。

See the docs here: https://github.com/marcogrcr/sequelize/blob/patch-1/docs/manual/other-topics/aws-lambda.md请参阅此处的文档: https : //github.com/marcogrcr/sequelize/blob/patch-1/docs/manual/other-topics/aws-lambda.md

const { Sequelize } = require("sequelize");

let sequelize = null;

async function loadSequelize() {
  const sequelize = new Sequelize(/* (...) */, {
    // (...)
    pool: {
      /*
       * Lambda functions process one request at a time but your code may issue multiple queries
       * concurrently. Be wary that `sequelize` has methods that issue 2 queries concurrently
       * (e.g. `Model.findAndCountAll()`). Using a value higher than 1 allows concurrent queries to
       * be executed in parallel rather than serialized. Careful with executing too many queries in
       * parallel per Lambda function execution since that can bring down your database with an
       * excessive number of connections.
       *
       * Ideally you want to choose a `max` number where this holds true:
       * max * EXPECTED_MAX_CONCURRENT_LAMBDA_INVOCATIONS < MAX_ALLOWED_DATABASE_CONNECTIONS * 0.8
       */
      max: 2,
      /*
       * Set this value to 0 so connection pool eviction logic eventually cleans up all connections
       * in the event of a Lambda function timeout.
       */
      min: 0,
      /*
       * Set this value to 0 so connections are eligible for cleanup immediately after they're
       * returned to the pool.
       */
      idle: 0,
      // Choose a small enough value that fails fast if a connection takes too long to be established.
      acquire: 3000,
      /*
       * Ensures the connection pool attempts to be cleaned up automatically on the next Lambda
       * function invocation, if the previous invocation timed out.
       */
      evict: CURRENT_LAMBDA_FUNCTION_TIMEOUT
    }
  });

  // or `sequelize.sync()`
  await sequelize.authenticate();

  return sequelize;
}

module.exports.handler = async function (event, callback) {
  // re-use the sequelize instance across invocations to improve performance
  if (!sequelize) {
    sequelize = await loadSequelize();
  } else {
    // restart connection pool to ensure connections are not re-used across invocations
    sequelize.connectionManager.initPools();

    // restore `getConnection()` if it has been overwritten by `close()`
    if (sequelize.connectionManager.hasOwnProperty("getConnection")) {
      delete sequelize.connectionManager.getConnection;
    }
  }

  try {
    return await doSomethingWithSequelize(sequelize);
  } finally {
    // close any opened connections during the invocation
    // this will wait for any in-progress queries to finish before closing the connections
    await sequelize.connectionManager.close();
  }
};

It's actually for sequelize, not knex, but I'm sure under the hood they work the same way.它实际上是为了续集,而不是 knex,但我确信在引擎盖下它们的工作方式相同。

I had this problem too, in my case it was cause i tried to connect db in production.我也遇到了这个问题,就我而言,这是因为我试图在生产中连接数据库。

so, I added ssl to Pool, like this:所以,我将 ssl 添加到池中,如下所示:

const pool = new Pool({
    connectionString: connectionString,
    ssl: {rejectUnauthorized: false},
});

Hope it helps you too...希望对你也有帮助...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Docker 节点应用程序 Postgres 错误“连接意外终止” - Docker Node App Postgres Error "Connection terminated unexpectedly" node-postgres,连接意外终止 - node-postgres, Connection terminated unexpectedly 使用“node postgres”的 Nodejs 应用程序在 GKE 中每 60 分钟“连接意外终止” - Nodejs application using "node postgres" having a "Connection terminated unexpectedly" every 60min in GKE NodeJS / psql:出现错误“连接意外终止” - NodeJS / psql: Getting error "connection terminated unexpectedly" PostgreSQL 错误:长时间查询的连接意外终止 - PostgreSQL error: Connection terminated unexpectedly for long queries 是什么原因导致AWS节点Lambda中的ECONNREFUSED,错误拒绝(本机)连接(本机)? - What causes a ECONNREFUSED, Connection refused at Error (native) in an AWS node Lambda? 与AWS RDS的AWS Node JS lambda连接 - AWS Node JS lambda connection to AWS RDS AWS Lambda postgres连接超时,但仅在首次尝试时 - AWS Lambda postgres connection timing out, but only on first attempt 如何在并发 AWS lambda 函数中管理 Postgres 连接? - How to manage Postgres connection in concurrent AWS lambda function? AWS Lambda:Redis ElastiCache 连接超时错误 - AWS Lambda: Redis ElastiCache connection timeout error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM