AWS Serverless デジタルバッジを取得する③　イベント駆動型アーキテクチャ編






[このデジタルバッジ](https://aws.amazon.com/jp/blogs/news/introducing-new-aws-serverless-digital-learning-badges/)取得のために、AWS Skill Builderの[このコース](https://explore.skillbuilder.aws/learn/lp/1585/serverless-learning-plan-japanese)を学習している記録

自分のスキルレベルは以下。
- SAAは取得
  - 4年前ぐらい
- 実務利用なし
  - 趣味レベルではあり





# Designing Event-Driven Architectures (Japanese)

https://explore.skillbuilder.aws/learn/course/14319/play/63373/designing-event-driven-architectures-japanese;lp=1585




## サーバーレス思考

- シンプルなサーバーレスパターン
  - 以下のような構成
    - クライアント
    - API Gateway
    - Lambda
    - DynamoDB
  - この構成の課題
    - クライアント
      - どこで問題が発生してもクライアントにエラー通知が行ってしまう。
    - API Gateway
      - API Gatewayは即時レスポンス
        - API Gatewayのタイムアウトは30秒
        - Lambdaのタイムアウトは15秒
    - Lambda
      - 再試行は組み込まれていないので、再試行・エラー処理の作成が必要





## サーバーレスイベント送信パターン

### Amazon SQS と Lambda の連携
同期だけでなく、非同期パターンも有効

- SQSを追加する
  - クライアント
  - API Gateway
    - API GatewayからSQSにリクエスト送信後、メッセージIDを取得。
  - SQS
    - メッセージをキューに格納
      - 永続保存されるので、デッドレターキューの設定等も検討
  - Lambda
    - キューをポーリングして関数呼び出し。
      - デフォルトで最大5つまでバッチ処理。
    - 標準 SQS キューと先入れ先出し (FIFO) SQS キューの両方が使用可能
      - 2019年までは標準のみだった。
    - 設定要素
      - 可視性タイムアウト
      - 遅延キュー
      - バッチサイズ
      - 再処理ポリシー
        - ポーリングはサービスが自動設定
  - DynamoDB

### AWS Step Functions を使用したワークフローオーケストレーション



- Step Functionsを追加する
  - クライアント
  - API Gateway
  - SQS
  - Lambda
    - StartExctution APIを実行してフロー開始
  - Step Functions
    - タスクのオーケストレーション
    - タスクの状態の追跡
    - ステップの成否の追跡
  - DynamoDB

- Step Functions でサポートされるエンタープライズメッセージングパターン
  - シーケンシャル
  - 条件選択
  - ループ
  - Try/catch/finally
  - 並列
- ワークフローの種類
  - 標準ワークフロー
  - Expressワークフロー
    - 大量
    - 短時間





### 参考資料

https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html

https://aws.amazon.com/about-aws/whats-new/2019/11/aws-lambda-supports-amazon-sqs-fifo-event-source/

https://docs.aws.amazon.com/step-functions/latest/dg/connect-to-resource.html#connect-wait-token

https://docs.aws.amazon.com/step-functions/latest/dg/concepts-standard-vs-express.html



## ステータスの更新を通信するパターン

- 呼び出し元のクライアントにステータスを提供する方法
  - クライアントのポーリング
  - Amazon Simple Notification Service (Amazon SNS) を使用するウェブフック
  - AWS AppSync を使用する WebSocket

### クライアントのポーリング


- 方式
  - クライアントがステータスをポーリング
  - Step Functionsがステータス更新
  - クライアントが結果をリクエスト
- メリット
  - 同期フローとの置換が簡単
- デメリット
  - データの整合性によるレイテンシーの増加
  - 何も変更されていない場合のリクエストとレスポンスの動作の無駄とコストの増加


### Amazon SNS を使用するウェブフック


- 方式
  - クライアントがWebhookを設定
  - Step FunctionsからSNSにステータス更新を通知
  - SNSがクライアントに通知
- メリット
  - リソース消費が少ない
- デメリット
  - クライアントがエンドポイントになる
    - SNSからの通知許可
    - クライアント側の起動状態
    - 再試行について検討が必要




### AWS AppSync を使用する WebSocket のパターン

AWS AppSync は、リアルタイムのデータ同期とオフラインのプログラミング機能を備えたフルマネージド GraphQL サービス。



- 方式
  - クライアントからAWS AppSync
  - AppsyncがDynamoDB・Step Functionsのステータス状態の同期を行う
- メリット
  - 構成がシンプルになり、リソース消費がより少ない
- デメリット
  - カスタマイズをしたい場合はAPI Gatewayを利用する




#### 参考資料

https://aws.amazon.com/appsync/
https://docs.aws.amazon.com/appsync/latest/devguide/welcome.html


## サーバーレスデータ処理パターン

### Amazon Kinesis を使用したデータ処理


ストリーム処理にKinesisファミリーを利用するケース。
従来のバッチ処理では応答性が得られない場合
- モバイルアプリケーションからのクリックストリームデータ
- アプリケーションログ
- ホームセキュリティカメラのフィード

**※ElasticsearchはAmazon OpenSearch Serviceに変更**


- プロデューサー
  - データレコードを追加
  - ライブラリ・ツール等でクライアント側に実装（？）
    - Kinesis Producer Library（KPL
    - AWS SDK
- ストリーム
  - Kinesis
  - Kinesis Date Firehose
- コンシューマー
  - Lambda
  - Kinesis Date Analytics
  - Kinesis Client Library (KCL) 


- 構成例
  - Kinesis Data Firehose を使用したサーバーレスデータ処理フロー
    - ストリーマー
      - Date Firehose
    - コンシューマー
      - S3
      - Lambda
      - 一度S3に格納してからデータ変換
    - ストレージ
      - S3
      - DynamoDB
      - Redshift
    - 解析
      - Athena
  - Kinesis Data Analytics を使用したサーバーレスデータ処理フロー
    - S3に格納する前にSQLを使用してリアルタイム分析
    - ストリーマー
      - Date Firehose
      - Kinesis analytics
        - SQLなどを渡して分析
      - Firehose
- Kinesis Data Streams と Kinesis Data Firehose の違い
  - Kinesis Data Firehoseのほうが簡素でユーザー管理要素が少ない
  - 詳細は参考資料参照


### Amazon SNS のフィルタリング、ファンアウト、ネストされたサーバーレスアプリケーション

- Amazon SNS メッセージのフィルタリング
  - パブリッシャー
    - Lambda
    - 属性をキー・値ペアで提供
  - SNS
    - すべてにサブスクライバーに配信
  - サブスクライバー
    - フィルタリングして対応するキー・値を処理
- ネストされたサーバーレスアプリケーション
  - 大規模なアプリケーションこれらの反復パターンを小規模なサーバーレスアプリケーションとして構築し、再利用するケース。
    - データのバックアップや、
    - 検索や分析用のデータのインデックス作成
- Amazon EventBridge
  - サーバーレスイベントバス
    - 疎結合なシステム・サービスを目指してAPIを作り続けたら、結果密結合になっちゃったので出来たサービス
    - APIを変更するのは困難なので、間にイベントバスとして挿入し、簡素化・制御を行う。
    - 本文上に記載が少なく、詳細は別の動画シリーズを案内されました。


### データ処理向けのストリーミングとメッセージング

- ストリームとメッセージングの比較
  - メッセージング
    - 個別のメッセージであり、メッセージレートが異なります。
    - 消費されると、メッセージは削除されます。
    - 障害に備えて再試行とデッドレターキューを設定します
  - ストリーミング
    - メッセージのストリームを一緒に確認します。ストリームは一般的に連続しています。
    - 一定期間にわたって、データはストリームに残ります。コンシューマーはポインタを維持する必要があります。
    - メッセージは、成功するか、期限切れになるまで再試行されます。レコードをバイパスするには、関数にエラー処理を構築する必要があります。


### 参考資料
https://docs.aws.amazon.com/sns/latest/dg/sns-subscription-filter-policies.html

https://docs.aws.amazon.com/eventbridge/latest/userguide/content-filtering-with-event-patterns.html

https://aws.amazon.com/jp/eventbridge/resources/#Webinars_and_videos

https://youtu.be/ohXgbcbYH7U


## イベント駆動型アーキテクチャにおける障害管理

### コードにおける障害管理
- 関数における障害管理
  - 再試行
- 同期イベントと非同期イベントのエラー処理
  - エラー種類
    - 関数エラー
      - Lambda イベントを正常にハンドオフ
      - 関数がエラーをスローする
      - 完了前にタイムアウトする
    - 呼び出しエラー
      - 関数がリクエストを受信する前にリクエストが拒否される
      - サイズの大きいペイロード
      - アクセス許可の欠如
      - 関数がスロットルされている
  - イベントソース
    - 同期イベントソース
      - API Gateway と Lambda 間のように、再試行は組み込まれていない
      - すべてのエラータイプのエラーと再試行を処理するコードを記述する必要がある
    - 非同期イベントソース
      - Amazon S3 などの非同期イベントソースでは、Lambda に再試行動作が組み込まれている
      - 再試行はSQSのような動作
- ストリームベースのイベントのエラー処理
  - Lambdaの設定オプションを使用してデフォルトの動作を変更することが有効
    - 関数エラー時のバッチ二等分
      - 失敗したバッチを２等分して再試行
    - 最大再試行回数
    - レコードの最大有効期間
    - 失敗時の送信先
      - 失敗したレコードをSNS・SQSに送信してオフライン処理
- 失敗したイベントの送信先
  - DLQではなく、Lambda 関数の失敗時の送信先を指定
    - SNS
    - SQS
    - Eventbridge
    - Lambda関数
  - メリット
    - DLQより利用できるものが多い。
    - 柔軟性
    - 成功時も通知することができる
- Amazon SQS をイベントソースとして使用するエラー処理
  - 以下の項目をカスタマイズする。
    - SQS
      - バッチサイズ
      - 可視性タイムアウト
    - Lambda
      - 処理時間
      - Lambdaの最大タイムアウト
        - 15分
      - 平均処理時間
      - 関数タイムアウト


### アプリケーション全体の障害管理
- AWS Step Functions
  - Lambdaの例外処理
  - Retryフィールド
    - DynamoDB呼び出し失敗のリトライ
  - Catchフィールド
    - エラーをキャッチ
- Amazon SQS
  - Lambda関数とSQSソースキューのDLQの差がある
  - [AWS Event Fork Pipelines](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:077246666028:applications~fork-event-replay-pipeline)
- AWS X-Ray
  - X-Rayは分散型トレース
    - システムをセグメント・サービスをサブセグメントと登録して追跡
    - 記録できるもの
      - AWS SDK で作成した AWS のサービスおよびリソースの呼び出し
      - 内部または外部の HTTP ウェブ API の呼び出し
      - SQL データベースクエリ



### 参考資料
https://qiita.com/yoshii0110/items/4ae10eb071565cb90b37


## まとめ・その他。

前のコースがLambda単体の内容だったけど、いきなり複数サービスを説明するコースで順序間違えたかと思いましたが、以下を見ると問題ないようです。


https://d1.awsstatic.com/training-and-certification/ramp-up_guides/Ramp-Up_Guide_Serverless.pdf


動画音声は日本語ではないですが、テロップなどは日本語です。
資料の中に**動画のトランスクリプト**として、翻訳したテキストはあります。

内容もサービス単体から、複数サービスを利用した内容となり、ボリュームとしてもいきなりレベルアップした感あります。
これ2時間で理解できる人はすごいんじゃないですかね…
※個人的には倍は必要な感覚です。

社内で利用している人がいたEventbridgeが出てきてよかったです。