【问题标题】:Bluebird with Lambda not returning data带有 Lambda 的蓝鸟不返回数据
【发布时间】:2016-11-07 22:57:57
【问题描述】:

我们有一个简单的查询,可以使用部署在 nodejs 上的无服务器应用程序从我们的数据库中获取信息。不幸的是,我无法从 Bluebird Promise 中得到任何响应——响应总是超时,我不确定是什么导致了这个问题。以下是我的文件:

serverless.yml:

service: myAuth0

provider:
  name: aws
  iamRoleARN: arn:aws:iam::XXXXXXXXX:role/test-role
  runtime: nodejs4.3
  stage: production
  region: us-us-1
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DeleteNetworkInterface"
      Resource: "*"
  vpc:
    securityGroupIds:
      - ${self:custom.${opt:stage, self:provider.stage}.${opt:region, self:provider.region}.vpc.securitygroup}
    subnetIds:
      - ${self:custom.${opt:stage, self:provider.stage}.${opt:region, self:provider.region}.vpc.subnet1}
      - ${self:custom.${opt:stage, self:provider.stage}.${opt:region, self:provider.region}.vpc.subnet2}

custom:
  production:
    us-east-1:
      vpc:
        subnet1: subnet-11111111
        subnet2: subnet-22222222
        securitygroup: sg-33333333

functions:
  getUserRoles:
    handler: app/handler.handle
    events:
      - http:
          method: get
          path: userstest/roles

handler.js:

'use strict';

require('dotenv').config();
var Promise = require('bluebird');
var getConn = require('./dbConn');

module.exports.handle = (event, context, callback) => {
  Promise.using(getConn(), function(conn){
    return conn.query('select ert.name from emp_roles ert order by ert.name').then(function(rows){
      let roles = [];
      rows.forEach(function(row){
        roles.push(row.name);
      });
      return roles;
    }).catch(function(err){
      console.log(error);
    });
  }).then(function(roles){
    console.log("found roles: " + roles);
    callback(null, {roles: roles});
  });
};

dbConn.js:

var mysql = require('promise-mysql');
var pool = mysql.createPool({
  connectionLimit: 10,
  host     : process.env.MYSQL_HOST,
  user     : process.env.MYSQL_USER,
  password : process.env.MYSQL_PW,
  database : process.env.MYSQL_DB
});

function getConn() {
  return pool.getConnection().disposer(function(connection) {
    pool.releaseConnection(connection);
  });
}

module.exports = getConn;

我添加了控制台日志条目,我可以看到它完成了它们......但是它没有返回任何内容,并且最终出现连接错误。我看到数据已被获取,而 Lambda 只是坐在那里 6 秒内没有返回任何内容。以下是来自 Cloud Watch 的最新条目:

18:15:01 开始请求 ID:195a7218-a516-11e6-b52d-5f028bb2bdf6 版本:$LATEST 18:15:01 2016-11-07T18:15:01.820Z 195a7218-a516-11e6-b52d-5f028bb2bdf6 找到角色:9 18:15:07 END RequestId:195a7218-a516-11e6-b52d-5f028bb2bdf6 18:15:07 报告 请求 ID:195a7218-a516-11e6-b52d-5f028bb2bdf6 持续时间:6002.14 毫秒 计费持续时间:6000 毫秒内存大小:1024 MB 使用的最大内存:18 MB 18:15:07 2016-11-07T18:15:07.468Z 195a7218-a516-11e6-b52d-5f028bb2bdf6 6.00 秒后任务超时

在将 Bluebird 与 Lambda 结合使用时,有什么问题吗?

【问题讨论】:

    标签: node.js lambda promise bluebird serverless-framework


    【解决方案1】:

    只是关于已接受答案的注释: 不建议使用 finally 块释放数据库连接。如果 Promise 链的生命周期出现问题,finally 可能不会被调用,从而导致资源泄漏。这在蓝鸟文档中有记录:http://bluebirdjs.com/docs/api/resource-management.html

    【讨论】:

      【解决方案2】:

      蓝鸟绝对有效。

      我认为使用 disposer 结束连接可能存在问题。我使用 postgresql promise 库,所以无法真正尝试使用 mysql,但我将其重写为使用 disposer,并且我得到相同的超时。

      尝试在 finally 块中结束连接。

      db.getConnection()
        .then(doMyQuery)
        .catch(catchErrors)
        .finally(db.disposeConnection)
      

      编辑:好的,实际上释放连接在 lambdas 中是不好的,你应该结束它们。 mysqljs 文档说:

      连接完成后,只需调用 connection.release() 并且连接将返回到池中,准备好再次使用 别人。

      你真的不想要那个。这就是为什么你会超时。当您的承诺链结束时,连接返回到池并等待再次使用,因此 lambda 超时,因为它永远不会结束。

      使用 connection.end() 或 connection.destroy()

      【讨论】:

      • 谢谢...不幸的是它仍然在回调超时(cb): var Promise = require('bluebird'); var pool = require('./dbConn'); module.exports.handle = (event, context, cb) => { pool.getConnection().then(function(conn){ conn.query(query).then(function(rows){ let roles = []; rows .forEach(function(row){ roles.push(row.name); }); cb(null, {roles: roles}); }).catch(function(err){ console.log(error); }) .finally(function(){ pool.releaseConnection(conn); }); }).catch(function(e){ callback(e); }); };
      • 你的新 dbConn 怎么样,看起来怎么样?编辑:我猜它现在只是返回一个池。
      • 感谢您的帮助!做到了!
      • @DavidD 很高兴为您提供帮助。你能告诉我它是否适合你的处理器?因为我很好奇为什么我在处理程序中结束连接时会超时。
      • 实际上它确实适用于处理程序,但是当您发现释放连接的问题时。我现在的连接方法如下: function getConn() { return pool.getConnection().disposer(function(connection) { connection.destroy(); //效果很好 //pool.releaseConnection(connection); //Timesout } ); }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      • 2016-04-30
      • 2023-03-28
      • 2015-08-28
      • 1970-01-01
      相关资源
      最近更新 更多