AWSラムダにおけるノード無サーバ機能のデバッグ


どのように多くの回、関数をローカルに書いて、それをテストし、それが唯一のAWSに展開したときに失敗するために動作していた?これはおそらくあなたが理解するよりも一般的です、そして、それは通常、ノードの誤解またはラムダ構成による問題に起因します.このポストでは、Serverlessな関数を書くとき、あなたが遭遇する最も一般的なデバッグ問題のいくつかをカバーします.

async / waitの不正利用


私が最初にノードでServerlessな関数を書き始めたとき.JSは、非同期関数がどのように振る舞うかを誤解していました.私は、非同期関数をバックグラウンドプロセスとして実行し、それ自身のスレッドで実行できるという印象を受けました.しかし、これはそうではありません.非同期関数は、ノードのコンテキストで実行されます.JSイベントループとバックグラウンドで実行されません.これは、バックグラウンドで非同期関数を実行しようとすると、イベントループをブロックし、関数が実行されない可能性があることを意味します.例えば、
const randomBackgroundFunction = async () => {
  console.log('This function may never run');
};

export const handler = async () => {
  // do some stuff ...

  randomBackgroundFunction(); // <-- this most likely won't run without an await
  await randomBackgroundFunction(); // <-- this function will definitely run

  return goodResponse;
};
私は「5月」と言います.他のコードが実行されず、イベントループがアイドル状態になっている場合、関数は実行されますが、ハンドラが戻ると、CPUクロックに対する競合です.AWSラムダの実装は、応答が実行されるか、ラムダのタイムアウトが到達した後にラムダをシャットダウンしようとします(このトピックに関してはより多くの!)それは可能です、あなたの呼び出しはシャットダウン・プロセスの存在の前に実行されるかもしれません、そして、あなたはそれが走った幸運を得ます.
今、あなたは“ダスティン、私はどのようにバックグラウンドで私の関数を実行し、実行を確保するか?”幸いにも、2つの大きな解決があります:非同期ラムダ呼び出しまたはAWSの単純な待ち行列サービス(SQS).

非同期ラムダ呼び出し


AWSは、箱機能のうちのasynchronous invocationsを持つためにラムダを構築しました.これは、プライマリハンドラからラムダを呼び出し、独自のスレッドで実行し、メインインスタンスをブロックしないことを意味します.このように、上記の例を書き換えることができます.
// background.js
export const handler = async () => {
  // do our background stuff like we may have before
  console.log('This function will definitely run');
}

// main.js
import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";

export const handler = async () => {
  // do some stuff ...
  const client = new LambdaClient(config);
  const command = new InvokeCommand({
    FunctionName: 'background',
    InvocationType: 'Event', // default here is 'RequestResponse'
  });

  await client.send(command); // this acts as a fire and forget

  return resp;
};
使用中のAPIについての詳細はAWS SDK v3 Docsを参照してください.我々がしていることは、ラムダにちょうどこの機能を引き起こして、応答を待たないようにするために'Event'呼び出しタイプを利用することです.Lambda's docs

Lambda manages the function's asynchronous event queue and attempts to retry on errors. If the function returns an error, Lambda attempts to run it two more times, with a one-minute wait between the first two attempts, and two minutes between the second and third attempts. Function errors include errors returned by the function's code and errors returned by the function's runtime, such as timeouts.


これで、我々はそれをセットアップしなければならなくて、我々自身を管理することなく、イベント待ち行列の利益を得ます.欠点は、ラムダのデフォルトのリトライ動作を使用して、より柔軟性を与えないエラーを処理することです.

AWS SQS


別のラムダを介して呼び出すように、我々はキューにメッセージを送信するためにSQSを利用することができますし、代わりに私たちの関数を実行している.上記の例と同様に、メッセージを生成することができます.これにより、設定可能なリトライ動作の利点が得られますが、キューを管理する必要があります.また、私たちのラムダは、ペイロードを解析することができる代わりに、SQSストリームからイベントデータを柔軟に読む方法を知っていなければなりません.

ラムダタイムアウト


ラムダのデフォルトタイムアウト設定は、次の主要なハードルです.あなたのラムダがしばらくの間実行する必要があるか、たくさんのデータを処理するならば、あなたの機能がちょうど突然終了して、あなたのコードの後の瞬間に達しないのを見るかもしれません.デフォルトでは、ラムダには6秒のタイムアウトがあります.あなたが追加サービス、長い実行している質問または寒さを始めるためにラムダを待っているならば、これは問題を証明することができました.ラムダのタイムアウトをチェックする簡単な方法は、AWSコンソールをロードし、ラムダの一般的な設定でページの下部にロードすることです.以下のスクリーンショットでは、私が検査しているラムダが5分のタイムアウトを持っているのを見るでしょう.

ラムダタイムアウトは15分まで2番目の間隔で設定することができます.私がServerlessなフレームワークを使用するとき、私は通常、APIゲートウェイに接続されているラムダを29秒に設定し、Sqsは設定ファイルを通して15分にトリガーします.APIゲートウェイの最大タイムアウトが30秒で、APIゲートウェイとラムダ間のレイテンシーのため、29秒を選択します.タイムアウトを設定するための配置構成オプションを使用しますが、それらを設定するかどうかを確認します.

見るべきもの


これらは比較的簡単なフィックスに直面した大きな問題の2つでした.以下はいくつかの小さな問題ですが、修正は簡単ですが、ラムダの利用に特有のものです.
  • ラムダがインタフェースを持つすべてのリソースにアクセスできるようにします.あなたの機能に接続されているIAMロールをコンソール経由でチェックして、パーミッションがどのパーミッションかを確認する必要があります.サーバーレスのフレームワークを使用している場合は、サーバーの設定ファイルにIAMパーミッションを設定できます.
  • 環境変数が正しく設定されていることを確認します.ラムダがアクセスする環境変数のコピーを保持し、AWSコンソールを介して確認できます.あなたの値があなたの設定から期待しているものと一致するようにしてください.
  • ファイルI/Oや大きなデータ操作をしているなら、メモリが不足していることを確認してください.あなたがいるならば、ラムダの新しい呪文記憶機能を利用してください.
  • 結論


    私はあなたが役立つこれらのヒントやトリックを見つけて、彼らはあなたの道を時間を節約!