我是无服务器框架的新手。 学习无服务器时的最佳实践。 here
我有一个关于“在Lambda代码之外初始化外部服务”的问题。 怎么实现呢? 例如:下面的handler.js中的代码
const getOneUser = (event, callback) => {
let response = null;
// validate parameters
if (event.accountid && process.env.SERVERLESS_SURVEYTABLE) {
let docClient = new aws.DynamoDB.DocumentClient();
let params = {
TableName: process.env.SERVERLESS_USERTABLE,
Key: {
accountid: event.accountid,
}
};
docClient.get(params, function(err, data) {
if (err) {
// console.error("Unable to get an item with the request: ", JSON.stringify(params), " along with error: ", JSON.stringify(err));
return callback(getDynamoDBError(err), null);
} else {
if (data.Item) { // got response
// compose response
response = {
accountid: data.Item.accountid,
username: data.Item.username,
email: data.Item.email,
role: data.Item.role,
};
return callback(null, response);
} else {
// console.error("Unable to get an item with the request: ", JSON.stringify(params));
return callback(new Error("404 Not Found: Unable to get an item with the request: " + JSON.stringify(params)), null);
}
}
});
}
// incomplete parameters
else {
return callback(new Error("400 Bad Request: Missing parameters: " + JSON.stringify(event)), null);
}
};
问题是如何在Lambda代码之外初始化DynamoDB。
更新2:
以下代码是否已优化?
Handler.js
let survey = require('./survey');
module.exports.handler = (event, context, callback) => {
return survey.getOneSurvey({
accountid: event.accountid,
surveyid: event.surveyid
}, callback);
};
survey.js
let docClient = new aws.DynamoDB.DocumentClient();
module.exports = (() => {
const getOneSurvey = (event, callback) {....
docClient.get(params, function(err, data)...
....
};
return{
getOneSurvey : getOneSurvey,
}
})();
答案 0 :(得分:7)
以下是有问题的引文:
在Lambda代码之外初始化外部服务
使用服务(如DynamoDB)时,请确保在lambda代码之外进行初始化。例如:模块初始化器(用于节点)或静态构造器(用于Java)。如果在Lambda函数内启动与DDB的连接,则该代码将在每次调用时运行。
换句话说,在同一个文件中,但在 - 之前 - 实际的处理程序代码之外。
let docClient = new aws.DynamoDB...
...
const getOneUser = (event, callback) => {
....
docClient.get(params, ...
当容器启动时,处理程序外部的代码将运行。当后续函数调用重用同一容器时,通过不再次实例化外部服务来节省资源和时间。容器经常被重用,但每个容器一次只处理一个并发请求,它们被重用的频率以及控制之外的时间......除非你更新函数,否则任何现有的容器将不再是重复使用,因为他们拥有旧版本的功能。
您的代码将按照书面形式运行,但尚未优化。
在当前一代Node.js Lambda函数(Node 4.x / 6.x)中出现的这种方法需要注意的是,某些对象 - 特别是那些创建与外部服务的文字持久连接的对象 - 将阻止事件循环变为空(一个常见的例子是mysql数据库连接,它与服务器保持实时TCP连接;相比之下,DynamoDB"连接"实际上是无连接的,因为它的传输协议是HTTPS)。在这种情况下,您需要采取不同的方法或allow lambda to not wait for an empty event loop才能冻结容器,方法是在调用回调之前将context.callbackWaitsForEmptyEventLoop
设置为false
...但仅在需要时才执行此操作如果你完全明白这意味着什么。默认情况下设置它是因为互联网上的某个人说这个好主意可能会带来神秘的错误。