« AWS Black Belt Online Seminar AWS上でのログ管理の資料およびQA公開 | メイン | AWS Black Belt Online Seminar「AWS re:Invent 2016 アップデート速報」資料およびQA公開 »

AWS Lambdaデッドレターキューによるロバストなサーバーレスアプリケーションの設計

Gene Ting, ソリューションアーキテクト

AWS Lambda はサーバーレスのイベント駆動コンピュートサービスです。 Lambda により開発者はクラウドに機能を簡単に追加できるようになりました。一方で、 Lambda の開発者が例外や障害を正常に処理するソリューションを作成することは、たびたび重要な課題となっています。いくつかの例を示します:

  • ファンクションが失敗した原因を運用サポートへ通知する
  • ジョブの重大な障害を通知したり、ジョブをリバランスするために、タイムアウトしたジョブをハンドラに送信する

今回の Lambda デッドレターキューのリリースにより、 Lambda ファンクションが失敗したときに、何が失敗の原因であったのかを通知できるようになりました。

この記事では、 Amazon SQS キューまたは Amazon SNS トピックに通知を配信するようにファンクションを設定する方法を説明します。また、 Lambda ファンクションが失敗したときに、どのようなプロセスでより意味のある通知を自動的に生成することができるのかを説明します。

Lambda デッドレターキューの紹介

デッドレターキューは強力な概念であり、ソフトウェア開発者は非同期処理コンポーネントでソフトウェアの問題パターンを見つけやすくなります。メッセージングコンポーネントがメッセージを受信し、メッセージの処理中に致命的または処理できなかったエラーを検出すると、別のキューや別の通知システムなど、失敗したメッセージに関する情報が送信されます。 SQS はすでにデッドレターキューを提供しており、さらに調査するために別のキューに処理できなかったメッセージを送信します。

AWS Lambda デッドレターキューは、 Lambda ファンクションで処理が失敗した際に、 Lambda サービスが非同期リクエストに関する情報を送信できる宛先として、 SQS キューまたは SNS トピックを設定することで有効化されます。 Lambda サービスは、リクエストがこれ以上リトライされなくなった際に、失敗したリクエストに関する情報を送信します。サポートされている呼び出しを示します。

  • カスタムアプリケーションからのイベント呼び出し
  • DynamoDB テーブル、 Amazon Kinesis ストリーム、または API Gateway リソースリクエスト統合以外のAWSイベントソース

AWS 上でサーバーレスアプリケーションを学ぶための典型的な初心者向けのユースケースとして、 S3 バケットにアップロードした画像からサムネイルを作成します。画像変換用の Lambda ファンクションは、変換エラーを SNS トピックに送信するように設定することができ、さらに調査するために Lambda ファンクションをトリガーします。

これで、既存の Lambda ファンクションのデッドレターキューを設定し、その機能をテストすることができます。

Lambda ファンクション用の DLQ ターゲットの構成

まず、 Lambda ファンクションの実行ロールが SNS トピックにパブリッシュできることを確認します。このデモでは、 sns-lambda-test トピックを使用します。例はこちら:

{
    "Version":"2012-10-17",
    "Statement":[{
       "Effect":"Allow",
       "Action":"sns:Publish",
       "Resource":"arn:aws:sns:us-west-2:123456789012:sns-lambda-test"
       }
    ]
}

SQS キューをターゲットにする場合は、適切な SendMessage アクションをキューに許可するポリシーが必要です。

次に、デッドレターキューを構成する既存の Lambda ファンクションを選択します。この例では、事前にデプロイされた CreateThumbnail ファンクションを選択します。

ファンクションを選択し、 Configuration を選択し、ページの中央にある Advanced settings セクションを展開し、 DLQ Resource フォームまでスクロールします。 SNS を選択し、 SNS Topic namesns-lambda-test と入力します。

これだけです。ファンクションが設定され、テストの準備が整いました。

障害通知処理

デッドレターキューのハンドラをテストする簡単な方法の1つは、失敗することがわかっている Lambda ファンクションでイベントを送信することです。この例では、画像の代わりにテキストファイルをS3バケットにアップロードし、サムネイル生成処理が画像ファイルではないとして認識し、エラーメッセージが付与された状態でハンドラが終了します。

Lambda が SNS トピックにエラー通知を送信すると、3つの追加のメッセージ属性が MessageAttributes オブジェクト通知に付与されます。

  • RequestID –リクエスト ID 。
  • ErrorCode - ハンドラが同期的に呼び出された場合に付与された HTTP 応答コード。
  • ErrorMessage - Lambda ランタイムによって返されたエラー・メッセージ。上記の例では、ハンドラからのエラーメッセージになります。

これらの属性に加えて、イベントの本体は Sns オブジェクトの Message 属性に保持されます。 SQS キューを代わりに使用すると、追加の属性は MessageAttributes オブジェクトにあり、イベント本文はメッセージの Body 属性に保持されます。

タイムアウト処理

Lambda ファンクションで発生する最も一般的な失敗の1つは、タイムアウトです。このシナリオでは、 Lambda ランタイムによって強制終了されるまで Lambda ファンクションが実行され、 Lambda ランタイムは次の例のようにファンクションがタイムアウトしたことを示すエラーメッセージを送信します。

"ErrorMessage": {
    "Type": "String", 
    "Value": "2016-11-29T04:27:36.789Z b4797725-b5eb-11e6-acb2-17876a085622 Task timed out after 300.00 seconds" 
}

エラーハンドラは、 Value 属性の Task timed out after の文字列を解析し、リクエストを複数の Lambda 呼び出しに分割したり、より多くのジョブを処理するために Auto Scaling グループ内の EC2 インスタンスをスピンアップするための別のキューを送信することができます。

重大な障害に対する処理

重大な障害の発生に対処するためには、別のシナリオが必要です。重大な障害の例を次に示します。

  • Lambda ハンドラの設定ミス
  • メモリ不足エラーなどのシステムクラッシュ

どちらの場合も、アプリケーションロジックでは正常に処理できる場合はほとんどありません。この種のエラーは、根本原因の分析のために運用サポートへ転送します。

システムクラッシュの場合、デッドレターキューには次のようなエラーメッセージを受け取ります。

"RequestID": { "Type": "String", "Value": "6502cad0-b641-11e6-bd4e-279609143c53" },
"ErrorCode": { "Type": "String", "Value": "200" },
"ErrorMessage": { "Type": "String", "Value": "Process exited before completing request" }

この例では、 Lambda ハンドラはメモリ不足エラーで強制的にクラッシュしました。詳細は Lambda ハンドラのログストリームを RequestID で検索することで見つけることができます。

設定ミスの場合、デッドレターキューは下記のエラーメッセージを受け取ります。

"ErrorMessage": { "Type": "String", "Value": "Cannot find module '/var/task/index'" }

この例では、 Lambda ハンドラの設定ミスにより、存在しない index.js モジュールをロードしようとしていました。

デッドレターキューが設定された Lambda ファンクションの監視

デッドレターキューが設定された Lambda ファンクションには、 CloudWatch メトリック "DeadLetterErrors" が付与されています。メトリックは、デッドレターメッセージペイロードをデッドレターキューに送信できないときに増加します。

まとめ

デッドレターキューのリリースにより、 Lambda ファンクション開発者はシンプルにビジネスロジックに集中することができます。エラーハンドリングは AWS Lambda インフラストラクチャにお任せください。

詳細については、 AWS Lambda 開発者ガイドのデッドレターキューを参照してください。 Happy coding everyone, 素晴らしいサーバーレスアプリケーションを作成することを楽しんでください!

(日本語訳はSA藤原が担当しました。原文は Robust Serverless Application Design with AWS Lambda Dead Letter Queues

コメント

Twitter, Facebook

このブログの最新情報はTwitterFacebookでもお知らせしています。お気軽にフォローください。

2018年4 月

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30