web-dev-qa-db-ja.com

タイムアウトエラーの後、AWSラムダ関数が動作を停止する

API呼び出しを非同期的に行い、データを返す単純なラムダ関数があります。これがうまくいく時間の99%。 APIがラムダで設定されたタイムアウトよりも長くかかると、予想どおりエラーが発生します。現在の問題は、ラムダ関数への後続の呼び出しを行うと、永久にタイムアウトエラーが発生することです。

 "errorMessage": "2016-05-14T22:52:07.247Z {session} Task timed out after 3.00 seconds"

これが事実であることをテストするために、ラムダタイムアウトを3秒に設定し、ラムダ内でこれらの2つの関数をトリガーする方法があります。

Javascript

function now() { 
    return response.tell('success'); 
}

function wait() {
    setTimeout(function() { return response.tell('success'); }, 4000);
}

now関数を呼び出しても問題はありません。 wait関数を呼び出すと、タイムアウトエラーが発生し、その後にnowを呼び出すと同じエラーが発生します。

これは予想される動作ですか?ラムダ関数への後続の呼び出しは動作するはずだと思います。私はいつでも設定タイムアウトを増やすことができると理解していますが、そうではありません。

35
jjbskir

関数ハンドルが特定のcontext.callbackWaitsForEmptyEventLoop

そのboolean-typeがfalseの場合、以前にラムダ呼び出しに応答/処理した可能性があるため、setTimeoutは発生しません。ただし、callbackWaitsForEmptyEventLoopの値がtrueの場合、コードは探していることを実行します。

また、「手書き」のタイムアウト、構成のタイムアウトの変更などを必要とせずに、コールバック経由ですべてを直接処理する方がおそらく簡単です...

例えば。

function doneFactory(cb) { // closure factory returning a callback function which knows about res (response)
  return function(err, res) {
    if (err) {
      return cb(JSON.stringify(err));
    }
    return cb(null, res);
  };
}

// you're going to call this Lambda function from your code
exports.handle = function(event, context, handleCallback) {

  // allows for using callbacks as finish/error-handlers
  context.callbackWaitsForEmptyEventLoop = false;

  doSomeAsyncWork(event, context, doneFactory(handleCallback));
};
15
Jakub Koral

関数構成で3秒を定義した場合、このタイムアウトはコード内の時間をオーバーライドするため、必ずラムダ関数構成のタイムアウトを増やしてwait()を再試行してください。

8
A.Elnaggar

私は同じ問題に遭遇しました。実際、Lambdaが応答しなくなる多くのケースがあります。例えば:

  1. 無効なJSONの解析:

    exports.handler = function(event, context, callback)
    {
        var nonValidJson = "Not even Json";
        var jsonParse = JSON.parse(nonValidJson);
    
  2. 未定義変数のプロパティへのアクセス:

    exports.handler = function(event, context, callback)
    {
        var emptyObject = {};
        var value = emptyObject.Item.Key;
    
  3. RDSにアクセスした後にmySql接続を閉じないと、Lambdaタイムアウトが発生し、応答しなくなります。

私が応答しないと言っているとき、それは文字通りロードさえもしていない、つまり、ハンドラー内の最初の印刷は印刷されず、Lambdaはタイムアウトですべての実行を終了します:

exports.handler = function(event, context, callback)
{
    console.log("Hello there");

これはバグであり、AWSチームによってほぼ1年間知られています。
https://forums.aws.Amazon.com/thread.jspa?threadID=238434&tstart=

残念ながら、それはまだ修正されていません。いくつかのテストの後、実際にはLambdaが再起動(コンテナのリロード?)を試みるため、時間が足りないことが明らかになりました。タイムアウトを10秒に設定すると、実行時間の約4秒後にLambdaが動作を開始し、次の実行では正常に動作するようになります。私も設定で遊んでみました:

context.callbackWaitsForEmptyEventLoop = false;

ハンドラ内にすべての「必須」ブロックを配置しても、実際には何も機能しませんでした。 Lambdaがデッドになるのを防ぐ唯一の方法は、より大きなタイムアウトを設定することです。このバグに対する回避策として10秒で十分です。

4
Slava Elantsev

AmazonコンソールのAWS構成では、デフォルトのタイムアウトを3秒から5秒以上に変更する必要があります

2
user2619052

タイムアウトを増やすだけでエラーは収まりました。 5秒に増やしました。私はこのLambdaをプロダクションで使用するつもりはなかったので、これは大丈夫でした。

0
Amaresh

問題は、AWS RDSインバウンド/アウトバウンドで言及しているIPアドレスによるものだと思います。

今のところテストしていて、node.jsがAWSではなくローカルideで動作している場合は、以下を実行する必要があります。

  1. AWS RDSに移動します。

  2. DBインスタンスをクリックします。

  3. そのDBインスタンスの名前をクリックします。
  4. 以下の「接続」セクションに移動して、セキュリティグループの役割を見つけます。
  5. セキュリティグループのタイプは、インバウンド、アウトバウンドになります。
  6. 両方を1つずつクリックします。新しいウィンドウが開きます。
  7. 繰り返しますが、インバウンドとアウトバウンドの2つのタブがあります。
  8. 両方をクリックします。
  9. 「編集」をクリックします。
  10. 「カスタム」ではなく「どこでも」を選択します。追伸インバウンド/アウトバウンドの両方で繰り返します。

準備完了。

0
Karan