无服务器框架的最佳实践
Best Practices in Serverless Framework
我是无服务器框架的新手。
在学习无服务器最佳实践时。
here
我有一个关于 "Initialize external services outside of your Lambda code" 的问题。
如何实施?
例如:下面的代码 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:
Is below code optimized?
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,
}
})();
这是有问题的引用:
Initialize external services outside of your Lambda code
When using services (like DynamoDB) make sure to initialize outside of your lambda code. Ex: module initializer (for Node), or to a static constructor (for Java). If you initiate a connection to DDB inside the Lambda function, that code will run on every invoke.
换句话说,在同一个文件中,但在实际处理程序代码之前。
let docClient = new aws.DynamoDB...
...
const getOneUser = (event, callback) => {
....
docClient.get(params, ...
容器启动时,处理程序外的代码运行。当后续函数调用重用同一个容器时,您可以通过不再实例化外部服务来节省资源和时间。容器经常被重用,但每个容器一次只能处理一个并发请求,它们被重用的频率和时间是你无法控制的……除非你更新功能,在这种情况下任何现有的容器将不再是重用,因为他们有旧版本的功能。
您的代码将按编写的方式运行,但未经过优化。
当前这一代 Node.js Lambda 函数(节点 4.x/6.x)中出现的这种方法的警告是某些对象——特别是那些创建与外部的字面持久连接的对象服务——将防止事件循环变空(一个常见的例子是 mysql 数据库连接,它保持与服务器的实时 TCP 连接;相比之下,DynamoDB“连接”实际上是无连接的,因为它是传输协议是 HTTPS)。在这种情况下,您需要在冻结容器之前采取不同的方法或 allow lambda to not wait for an empty event loop,方法是在调用回调之前将 context.callbackWaitsForEmptyEventLoop
设置为 false
...但只有在需要时才这样做如果你完全理解它的意思。默认设置它,因为互联网上有人说这是个好主意,以后可能会给您带来神秘的错误。
我是无服务器框架的新手。 在学习无服务器最佳实践时。 here
我有一个关于 "Initialize external services outside of your Lambda code" 的问题。 如何实施? 例如:下面的代码 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:
Is below code optimized?
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,
}
})();
这是有问题的引用:
Initialize external services outside of your Lambda code
When using services (like DynamoDB) make sure to initialize outside of your lambda code. Ex: module initializer (for Node), or to a static constructor (for Java). If you initiate a connection to DDB inside the Lambda function, that code will run on every invoke.
换句话说,在同一个文件中,但在实际处理程序代码之前。
let docClient = new aws.DynamoDB...
...
const getOneUser = (event, callback) => {
....
docClient.get(params, ...
容器启动时,处理程序外的代码运行。当后续函数调用重用同一个容器时,您可以通过不再实例化外部服务来节省资源和时间。容器经常被重用,但每个容器一次只能处理一个并发请求,它们被重用的频率和时间是你无法控制的……除非你更新功能,在这种情况下任何现有的容器将不再是重用,因为他们有旧版本的功能。
您的代码将按编写的方式运行,但未经过优化。
当前这一代 Node.js Lambda 函数(节点 4.x/6.x)中出现的这种方法的警告是某些对象——特别是那些创建与外部的字面持久连接的对象服务——将防止事件循环变空(一个常见的例子是 mysql 数据库连接,它保持与服务器的实时 TCP 连接;相比之下,DynamoDB“连接”实际上是无连接的,因为它是传输协议是 HTTPS)。在这种情况下,您需要在冻结容器之前采取不同的方法或 allow lambda to not wait for an empty event loop,方法是在调用回调之前将 context.callbackWaitsForEmptyEventLoop
设置为 false
...但只有在需要时才这样做如果你完全理解它的意思。默认设置它,因为互联网上有人说这是个好主意,以后可能会给您带来神秘的错误。