3

我是无服务器框架的新手。学习无服务器最佳实践时。 这里

我有一个关于“在您的 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:

下面的代码优化了吗?

处理程序.js

let survey = require('./survey');
module.exports.handler = (event, context, callback) => {
    return survey.getOneSurvey({
      accountid: event.accountid,
      surveyid: event.surveyid
    }, callback);
};

调查.js

let docClient = new aws.DynamoDB.DocumentClient();
module.exports = (() => {
  const getOneSurvey = (event, callback) {....
      docClient.get(params, function(err, data)...
      ....
  };

  return{
     getOneSurvey : getOneSurvey,
  }
})();
4

1 回答 1

7

这是有问题的报价:

在 Lambda 代码之外初始化外部服务

使用服务(如 DynamoDB)时,请确保在 lambda 代码之外进行初始化。例如:模块初始化器(用于 Node),或静态构造器(用于 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)。在这种情况下,您需要采取不同的方法或允许 lambda在冻结容器之前不等待空事件循环context.callbackWaitsForEmptyEventLoop,方法是设置为false在调用回调之前......但只有在需要并且只有当您完全理解它的含义时才这样做。默认设置是因为网上有人说这是个好主意,以后可能会给你带来神秘的错误。

于 2016-07-07T10:44:18.537 回答