带有 Knex JS 和 RDS Postgres 的 AWS Lambda

Rya*_*rup 7 postgresql knex.js aws-lambda

我一直在做一些研究,但找不到关于在 Lambda 函数中使用 Knex JS 的好答案:

如何将 Knex 与 AWS Lambda 结合使用?第1875章

使用 Apex 和 AWS Lambda 的无服务器 URL 缩短器

在 AWS lambda 中使用 Promise.all()

这是我在 index.js 中的内容:

const knex = require('knex')({
  client: 'pg',
  connection: {...},
});

exports.handler = (event, context, callback) => {
  console.log('event received: ', event);
  console.log('knex connection: ', knex);

  knex('goals')
    .then((goals) => {
      console.log('received goals: ', goals);
      knex.client.destroy();
      return callback(null, goals);
    })
    .catch((err) => {
      console.log('error occurred: ', err);
      knex.client.destroy();
      return callback(err);
    });
};
Run Code Online (Sandbox Code Playgroud)

我能够在本地连接和执行我的代码,但是当它部署到 AWS 时我遇到了一个有趣的错误——第一次调用总是成功,但之后的任何事情都失败了。我认为这与 knex 客户端被销毁有关,但随后尝试在下一次调用中再次使用。如果我重新上传我的 index.js,它会恢复到一次调用,然后失败。

我相信这可以使用 Promise 以某种方式解决,但这是我第一次使用 Lambda,所以我不熟悉它如何在后续调用中管理与 RDS 的连接。在此先感谢您的任何建议!

Hon*_*iao 7

For me, it worked on my local machine but not after deploying. I was kind of be mislead.

It turns out the RDS inbound source is not open to my Lambda function. Found solution at AWS Lambda can't connect to RDS instance, but I can locally?: either changing RDS inbound source to 0.0.0.0/0 or use VPC.

After updating RDS inbound source, I can use Lambda with Knex successfully.

The Lambda runtime I am using is Node.js 8.10 with packages:

knex: 0.17.0
pg: 7.11.0
Run Code Online (Sandbox Code Playgroud)

The code below using async also just works for me

knex: 0.17.0
pg: 7.11.0
Run Code Online (Sandbox Code Playgroud)

Hopefully it will help people who might meet same issue in future.


das*_*mug 1

在 AWS Lambda 中处理数据库连接的最可靠方法是在调用过程本身连接断开与数据库的连接。

在上面的代码中,由于您在第一次调用后已经断开连接,因此第二次调用不再有连接。

要修复它,只需移动您的knex.

exports.handler = (event, context, callback) => {
  console.log('event received: ', event);

  // Connect
  const knex = require('knex')({
    client: 'pg',
    connection: {...},
  });

  console.log('knex connection: ', knex);

  knex('goals')
    .then((goals) => {
      console.log('received goals: ', goals);
      knex.client.destroy();
      return callback(null, goals);
    })
    .catch((err) => {
      console.log('error occurred: ', err);
      // Disconnect
      knex.client.destroy();
      return callback(err);
    });
};
Run Code Online (Sandbox Code Playgroud)

有多种方法可以重用现有连接,但成功率差异很大,具体取决于数据库服务器配置和生产负载。