AWS Lambda与Knex JS和RDS Postgres

时间:2018-01-16 17:37:29

标签: postgresql aws-lambda knex.js

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

How do I use Knex with AWS Lambda? #1875

Serverless URL Shortener with Apex and AWS Lambda

Use Promise.all() in AWS lambda

以下是我在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);
    });
};

我能够在本地连接并执行我的代码,但是当它部署到AWS时我遇到了一个有趣的错误 - 第一次调用总是成功,但是任何事情都失败了。我认为这与knex客户端被破坏有关,但后来尝试在下次调用时再次使用。如果我重新上传我的index.js,它会回到一个呼叫的工作,然后失败。

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

3 个答案:

答案 0 :(得分:0)

对我来说,它可以在我的本地计算机上运行,​​但在部署后却无法运行。我有点被误导了。

事实证明,RDS入站源未对我的Lambda函数开放。在AWS Lambda can't connect to RDS instance, but I can locally?找到了解决方案:将RDS入站源更改为0.0.0.0/0或使用VPC。

更新RDS入站源后,我可以成功使用Lambda与Knex。

我正在使用的Lambda运行时是Node.js 8.10,带有以下软件包:

knex: 0.17.0
pg: 7.11.0

下面使用async的代码也对我有用

const Knex = require('knex');

const pg = Knex({ ... });

module.exports.submitForm = async (event) => {
  const {
    fields,
  } = event['body-json'] || {};

  return pg('surveys')
    .insert(fields)
    .then(() => {
      return {
        status: 200
      };
    })
    .catch(err => {
      return {
        status: 500
      };
    });
};

希望它将对将来可能遇到相同问题的人们有所帮助。

答案 1 :(得分:0)

我遇到了与您所说完全相同的问题:在 AWS lambda 函数中使用了 destroy()(例如:在底部等待 knex.destroy()),突然我所有的 AWS lambda 都出错了。

因为我没有怀疑,所以我搜索了几个小时导致问题的原因,甚至开始使用 lambda + vpc + nat 等进行调查。结果只是 AWS 以某种方式冻结了 lambda,如果您破坏了连接,在下一次调用处理程序时,它将尝试重用连接。

解决方案:不要在 lambda 末尾使用 .destroy() 并重新部署。

答案 2 :(得分:-1)

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

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

要修复它,只需移动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);
    });
};

有多种方法可以重用现有连接,但成功率因数据库服务器配置和生产负载而异。