1

nodejs にデプロイされたサーバーレス アプリケーションを使用して、データベースから情報をフェッチする簡単なクエリがあります。残念ながら、Bluebird promise から応答を得ることができません。応答は常にタイムアウトになり、何が問題を引き起こしているのかわかりません。以下は私のファイルです:

サーバーレス.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

ハンドラ.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 秒間何も返さずにそのまま待機していることがわかります。以下は、クラウド ウォッチからの最新のエントリです。

18:15:01 START RequestId: 195a7218-a516-11e6-b52d-5f028bb2bdf6 バージョン: $LATEST 18:15:01 2016-11-07T18:15:01.820Z 195a7218-a516-11e6-b52d-5 f028bb2bdf6 68 個の役割が見つかりました: :15:07 END RequestId: 195a7218-a516-11e6-b52d-5f028bb2bdf6 18:15:07 REPORT RequestId: 195a7218-a516-11e6-b52d-5f028bb2bdf6 期間: 6002.14 ミリ秒 請求期間: 6000 ミリ秒 使用メモリ 4 MB 最大 10 : 18 MB 18:15:07 2016-11-07T18:15:07.468Z 195a7218-a516-11e6-b52d-5f028bb2bdf6 6.00 秒後にタスクがタイムアウトしました

Lambda で Bluebird を使用すると壊れるものはありますか?

4

2 に答える 2

1

受け入れられた回答についてのメモ: finally ブロックを使用してデータベース接続を解放することはお勧めしません。promise チェーンのライフサイクルで何かが壊れた場合、finally呼び出されない可能性があり、リソース リークが発生する可能性があります。これは、bluebird のドキュメントに記載されています: http://bluebirdjs.com/docs/api/resource-management.html

于 2017-01-08T05:50:18.047 に答える
0

ブルーバードは間違いなく機能します。

ディスポーザーを使用して接続を終了すると問題が発生する可能性があると思います。私はpostgresql promiseライブラリを使用しているため、mysqlを実際に試すことはできませんが、ディスポーザーを使用するように書き直したところ、同じタイムアウトが発生しました。

finally ブロックで接続を終了してみてください。

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

編集:わかりました、実際に接続を解放することはラムダでは悪いです。それらを終了する必要があります。mysqljs のドキュメントには次のように書かれています。

接続が完了したら、connection.release() を呼び出すだけで、接続がプールに戻り、他の誰かが再び使用できるようになります。

あなたは本当にそれを望んでいません。そのため、タイムアウトが発生します。Promise チェーンが終了すると、接続はプールに戻り、再び使用されるのを待つため、終了しないためラムダがタイムアウトします。

connection.end() または connection.destroy() を使用する

于 2016-11-08T15:49:38.840 に答える