AWS Well-Architected Lens – Serverless Applications まとめ 信頼性編
アーキテクチャを検討する上で、とても役に立つフレームワークであるAWS Well Archtected Framework。
サーバーレス版が公開されたのでベストプラクティスについてまとめておきます。
https://d1.awsstatic.com/whitepapers/architecture/AWS-Serverless-Applications-Lens.pdf
運用編、セキュリティ編、信頼性編、パフォーマンス編、コスト編の5回に分けてメモしていきます。
解釈が間違っているかもしれないので、ご注意ください。
SERVREL 1:ピークワークロードのサーバレス制限を考慮しましたか?
- サービスの不正使用から守るために、デフォルトのサービス制限がある。
- 適切に制限を監視しないと、サービスの劣化または抑制をもたらす可能性がある。
- 多くの制限はソフトリミットであり、それを超える場合は上限緩和申請することができる。
- AWS Trusted Advisorを使用して、サービスが制限の80%を超えているかどうかを検出できる。
- また、ワークロードの超過が予測される場合は、事前に制限を引き上げることもできる。
- 制限を引き上げる場合は、スケール対応したりサービス不能攻撃を吸収するために、サービス制限と最大使用量との間に十分なギャップがあることを確認する。
- 関連するすべてのアカウントとリージョンでこれらの制限を考慮する必要がある。
- さらに、Lambdaの同時実行制限機能を使用して、ビジネスクリティカルなパスを分離し、予期しないイベントの負荷が他のリソースに影響しないようにする必要がある。
- プロファイル、脅威モデル、および組織構造によって、異なるアカウントのワークロードを分離することも推奨される。
- 同時実行数の管理 - AWS Lambda
- サーバレスアプリケーションがスパイクするかどうかに関わらず、非同期パターンに従って、サーバレスアプリケーションをより弾力性のあるアプリケーションに設計する。
SERVREL 2:サーバーレスアプリケーションへのアクセスレートをどのように規制していますか?
- リクエストの数が、バックエンドで処理できる処理数を超えると、サービスAPIが影響を受ける可能性がある。
- 契約プランによってアクセスパターンをコントロールするには、APIレベルでスロットリングを有効にする必要がある。
- API内の適切なHTTPステータスコード(スロットル用の429など)を返すことで、それに応じてリトライを行いスロットリングされたアクセスを処理するのに役立つ。
- より細かい制御は使用量プランとAPIキー発行で可能となる。疑わしいリクエストをしている場合、管理者が簡単にアクセスを切断することもできる。
- APIキーを取得する一般的な方法は、開発者ポータルを用意する方法です。これにより、サービスプロバイダとして、コンシューマとリクエストに関連付けられた追加のメタデータが提供される。
- アプリケーション、連絡先情報、ビジネスエリア/目的をキャプチャし、DynamoDBのようなデータストアに格納します。
- これにより、コンシューマーの追加検証とIDによるロギングのトレーサビリティが提供され、コンシューマーに変更のアップグレード/問題を連絡することができる。
SERVREL 3:サーバーレスのアーキテクチャー内での非同期呼び出しとイベントに関する戦略は何ですか?
- 非同期呼び出しは、HTTPレスポンスの待ち時間を短縮する。イベントドリブンアーキテクチャにより、非同期でコードを実行できるため、待ち時間が制限される。
- フロントエンドシステムは、全体の実行が完了するまでブロックするのではなく、最初のリクエストでジョブIDを受け取り、そのステータスをポーリングする。
- イベントループ、並行処理技術を使用してアプリケーションの一部を遅延ロードすることによって、フロントエンドをより効率的にすることができる。
- また、フロントエンドは、カスタムリトライとキャッシングによってより堅牢になるため、非同期呼び出しでは重要な要素になる。
- また、同期呼び出しが必要な場合は、実行全体がAPI Gatewayの最大タイムアウトを超えないようにし、その調整が外部サービス(AWSステップ関数など)によって行われていることを確認することをお勧めする。
- リクエストライフサイクルに沿って発生する可能性があります。
SERVREL 4:サーバーレスアプリケーションのテスト戦略は何ですか?
- テストは、通常、ユニットテスト、統合テスト、受入れテストによって行われる。堅牢なテスト戦略を開発することで、さまざまな負荷や状況下でサーバレスアプリケーションをエミュレートできる。
- 単体テストはサーバーレスではないアプリケーションと異なるものであってはならず、必要な変更を加えずにローカルで実行できる。
- 統合テストは、制御できないサービスを模倣すべきではありません。実稼働環境とまったく同じ環境を提供できるため、実際のサービスを使用する。
- 受け入れまたはエンドツーエンドテストは固有の推奨事項はありません。
- 一般に、AWS Marketplaceで利用可能なLAmbdaおよびサードパーティのツールは、パフォーマンステストのコンテキストでテストハーネスとして使用できる。
- パフォーマンステスト中の注意点を次に示す。
- 呼び出された最大メモリなどのメトリクスは、CloudWatchログで確認できる。メトリクスは、最適なメモリーと適切なタイムアウト値を示す場合がある。
- Lambda機能がVPC内で実行されている場合は、サブネット内の使用可能なIPアドレス空間に注意する。
- モジュール化されたコードをハンドラの外部にある別々の関数に作成することにより、より多くのユニットテスト可能な関数が可能になる。
- Lambda関数の静的コンストラクタ/初期化コード(つまり、グローバルスコープ、ハンドラの外側)で参照される外部化された接続(リレーショナルデータベースへの接続プールなど)を確立すると、Lambda実行の場合に外部接続のしきい値に到達しない環境が再利用される。
- それに応じてDynamoDBの読み書きテーブルのスループットを調整し、パフォーマンステストサイクル全体のスループットの変化に対応するように自動スケーリングを設定する。
SERVREL 5:サーバレスアプリケーションにどのように弾力性を持たせていますか?
- 変更が失敗した場合に以前のバージョンに戻すことができると、サービスの可用性が保証される。
- まず、監視メトリクスを配置する必要がある。環境負荷の「正常」状態を判断し、CloudWatchで適切なメトリクスとしきい値パラメータを定義して、「正常でない」状態を過去のデータに基づいて判断する。
- また、デプロイを監視し、自動化されたアクションを実装する。Lambda機能のバージョニングやAPIバージョンなどの機能を使用すると、デプロイが失敗した場合に以前の状態に戻すことができる。
- サーバーレスアプリケーションの特定の部分は、pub / subなどのパターンを使用して、イベント駆動型のさまざまなコンポーネントへの非同期呼び出しによって指定される。
- 非同期呼び出しに失敗した場合は、できるだけキャプチャしてリトライする必要がある。そうしないとデータが失われる可能性があり、ユーザーエクスペリエンスが低下する可能性がある。
- Lambda関数については、Lambdaクエリにリトライロジックを組み込んで、スパイキーなワークロードがバックエンドを圧倒しないようにする。
- また、Lambdaロギングライブラリを活用して、CloudWatchログにエラーを追加しカスタムメトリクスとして取得する。
- AWS SDKは、ほとんどの場合に、デフォルトでバックオフとリトライのメカニズムを提供している。しかし、ニーズに合わせて調整するべきです。
- AWS X-RayおよびサードパーティのAPM(Application Performance Monitoring)ソリューションを使用すると、分散トレースでスロットリングを識別したり、待ち時間にどのような影響が生じるのかを把握できる。
- 失敗する可能性のある非同期呼び出しの場合、個々のLambda関数に対してデッドレターキュー(DLQ)を有効にし、専用のDLQリソース(Amazon SNSとAmazon Simple Queue Service(Amazon SQS)を使用)を作成することをお勧めする。
- 可能な限り、Step Functionsを使用して、サーバーレス・アプリケーション内のカスタム試行/キャッチ、バックオフ、およびリトライの量を最小限に抑える必要がある。
- さらに、PutRecords(Kinesis)やBatchWriteItem(DynamoDB)などの操作では、部分的な障害が発生した場合でも正常に返されるので、常に応答を検査し、プログラムで対処する必要がある。
- トランザクションベースの同期処理の場合、Sagaパターンで説明されているように、アプリケーションのロジックを分離し単純化したStep Functionsを使用することによってロールバックを達成できる。