我一直在做一些研究,但我无法找到一个关于在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的连接。提前感谢任何建议!
答案 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);
});
};
有多种方法可以重用现有连接,但成功率因数据库服务器配置和生产负载而异。