[レポート] AWS Lambdaを使用したマイクロサービスの構築 #SVS343 #reinvent
CX事業本部の佐藤です。
re:Invent 2019 「Building microservices with AWS Lambda」のセッションレポートです。
セッション概要
Many developers have become familiar with building microservices on traditional compute offerings such as virtual machines and containers, but what about serverless? The "functions as a service" model behind AWS Lambda presents a number of unique differences while still providing many benefits that make it a strong fit for microservices-based architectures. In this session, we talk about mapping microservices-based architectures to Lambda's event model. You learn how to think about the bounds of functions and their alignment to the services represented. We then cover patterns that enable rapid development and easier testing. Walk away ready to build your next microservice with AWS Lambda.
多くの開発者は、仮想マシンやコンテナなどの従来のコンピューティング製品でマイクロサービスを構築することに慣れてきましたが、サーバーレスはどうですか? AWS Lambdaの背後にある「サービスとしての機能」モデルには、多くの固有の違いがありますが、それでもマイクロサービスベースのアーキテクチャに強力に適合する多くの利点があります。 このセッションでは、マイクロサービスベースのアーキテクチャをLambdaのイベントモデルにマッピングする方法について説明します。 関数の境界と、それらが表されるサービスとの整合性について考える方法を学びます。 次に、迅速な開発と簡単なテストを可能にするパターンを扱います。 AWS Lambdaで次のマイクロサービスを構築する準備をしてください。
レポート
はじめに
containers != microservices, microservices != containers コンテナはマイクロサービスではない、マイクロサービス=コンテナでもない
今日話すこと
AWS Lambda + Microservicesについてお話しします。
単一のサービスのビュー
- フロントで動作するパブリックなAPI
- 非同期な内部API
一般的なAWSマイクロサービスパターン
フロントのAPI
フロントのAPIは基本的には同期的な通信で行う。クライアントはHTTPSであることが多い。API GatewayからLambdaを実行するところまで。
- 同期通信
- HTTPSクライアント
- APIゲートウェイまたはロードバランサー
- 柔軟なクライアントインターフェイス
- クライアントに対するセキュリティ保護
非同期なバックエンド
API GatewayからLambdaを実行し、その後キューなどに格納して結果整合性な処理では以下のような非同期通信で行います。
- 非同期通信
- シンプルなクライアント
- キュー、トピック、バス、ストリーム
- イベント/メッセージ
- エクスポーネンシャルバックオフ
今日は簡単なアプリケーションにフォーカスを当てます
- パブリックなインターフェイス
- プライベートな内部バックエンドサービス
Lambda API
- Lambdaによって提供されるAPI
- すべてのモデルでLambdaを呼び出す
- 他のすべてのサービスで使用されます
- 同期と非同期をサポート
- 必要なイベントペイロード構造を渡すことができます
- すべてのSDKに含まれるクライアント
APIへのアクセス方法
LambdaのAPIを公開するためには3つのオプションがあります
- API Gateway
- Application Load Balancer
- AppSync
APIフロントサービスのチートシート
APIを公開するサービスを選定する際の以下のチートシートがわかりやすかったです。参考になりました。WebAPIを作成する場合、API Gatewayよりも Appcalition Load Balancerを使う方がユースケースに合っている場合もありそうです。
- 複数のデータソースまたはデータに対する非常にユニークなクエリを備えた複雑なAPIですか?
- AWS AppSync
- WebSocketを使いたい場合
- Amazon API Gateway
- 変換、スロットリング、使用プラン、柔軟な認証が必要ですか?
- Amazon API Gateway
- 通常のAPI、1か月あたり潜在的に高いリクエスト、追加の変換機能は不要ですか?
- Application Load Balancer
- その他:通常のAPI、1か月あたり数千万件のリクエスト?
- Amazon API Gateway
Authorization
認証については、認証を行わないオープンなもの、IAMを使うもの、Cognitoオーソライザーを用いるもの、サードパーティ性の認証機構を使うもの(Auth0)など様々です。基本的にはCognitoオーソライザーやLambdaオーソライザーを使うかと思います。
- オープンAPI
- 認証または承認なし
- AWS Identity and Access Management(IAM)アクセス許可
- IAMポリシーとAWS認証情報を使用してアクセスを許可します
- Amazon Cognitoオーソライザー
- Amazon Cognitoは認証用の管理ユーザーディレクトリです
- Amazon Cognitoユーザープールに接続し、OAuthスコープと一緒に有効化する
- Lambdaオーソライザー
- Lambdaを使用して、ベアラートークン(例としてOAuthまたはSAML)を検証するか、パラメーターを要求し、アクセスを許可する
リクエストのルーティングを処理する場所の簡単な説明
リクエストのルーティングの責務をどのレイヤで行うかです。
- バックエンドロジックへのルーティングは誰が処理する必要がありますか?
- 特定のフレームワークは、そのロジックをいずれかの場所に配置します。
Lambda + in function ルーティングモデル
リクエストのルーティングをLambda側で行う手法です。
前述の特性は、Function ルーティングモデルを使用して、顧客を「危険ゾーン」に入れる要因です。
- 全体に適用されるセキュリティ構造
- 全体に適用されるパフォーマンス設定
- AWS Step Functionsを使用してロジックを他の関数にチェーンアウトする方が良い場合があります
- 非同期モデルを介して "Lambda-lith"は複雑になりすぎて、ロジックルーティングモデル全体を再考し続けることができます。
要求ルーティングを処理する場所
ルーティングするレイヤをAPI Gatewayを使用した場合の利点は、API Gatewayのマネージドの機能が使えることやAWSのツールとの互換性が向上します。まだ、セキュリティの粒度やパフォーマンスも向上します。逆にLambdaでルーティングを処理した場合は、ネイティブコードと特定のフレームワークなどを使用できる(NodeだとExpressとか)。また、ベンダーロックインがないため、コードの移植性が向上するなどが挙げられます。また、コールドスタートが軽減する場合もあるそうです。
- チームAPIゲートウェイ
- API Gatewayの利点の使用
- AWSのツールとの互換性の向上
- セキュリティの粒度の向上
- パフォーマンスの粒度の向上
- コードのチーム
- ネイティブコード/フレームワーク機能
- コードの移植性が向上する可能性がある
- セキュリティ構造(IAMの役割、ポリシーなど)
- コールドスタートが減る?
正直なところどちらが良いかは、賛否両論です。顧客からのフィードバックは非常に分かれています。もし特定のフレームワークを気に入っているであればそれを使えば良いと思います。実行するコードの量を減らして減らしたい場合は、API Gatewayに処理をオフロードするのも良いかもしれません。
同期API
誰が再試行しますか? どれだけの時間?
これにより障害からの回復が困難になる「密結合」が作成されます。
非同期API
同期APIを以下のような非同期APIアーキテクチャに変更することで、上記の「密結合」問題解消して、「疎結合」なコンポーネントになります。
比較する方法
- スケール/並行性
- 制御
- 耐久性
- 持続性
- 再試行
- 価格
- 消費
非同期イベントソースの最近の発表
- Lambdaの呼び出しソースとしてのSQS FIFO
- SNSデッドレターキュー(DLQ)
- Lambda宛先:
- 関数から成功/失敗をキャプチャする
- ストリーミングイベントの場合:
- MaximumRetryAttempts、MaximumRecordAgeInSeconds、BisectBatchOnFunctionError、失敗時の宛先バッチウィンドウ *並列化係数
- 非同期イベントの場合:
- MaximumRetryAttempts MaximumEventAgeInSeconds
非同期サービス決定のチートシート
AWSのキューサービスを選定する際のチートシートです。いろいろなサーバーレスのセッションを見てきましたが、EventBridgeをキューとして使う事例がとても多かったです。
- 大量のスループット/注文/複数の消費者/リプレイ?
- Kinesis Data Streams
- 1つからほとんど1つまたは最小限のファンアウトで、Lambda / HTTPターゲットに直接接続しますか?
- Amazon SNS
- バッファーは、注文するかどうかにかかわらず、消費できるようになるまでリクエストを送信しますか?
- Amazon SQS
- 1対多のファンアウト、多くの異なる消費者ターゲット、スキーママッチング、きめ細かいターゲットルール?
- EventBridge
AWS Lambda環境変数
- Functionに動的に渡すことができるキーと値のペア
- Node.jsのprocess.envやPythonのos.environなどの標準環境変数APIを介して利用可能
- AWS Key Management Service(AWS KMS)を使用してオプションで暗号化できます
- IAMでアクセスするロールを指定できます
- ステージごとに環境を作成するのに役立つ情報(つまり、開発、テスト、本番)
Lambdaレイヤーを使用する
- 共通コンポーネントをZIPファイルに入れて、Lambdaレイヤーとしてアップロードします
- レイヤーは不変であり、更新を管理するためにバージョン管理できます
- バージョンが削除されるか、使用する権限が取り消されると、それを使用していた機能は引き続き機能しますが、新しいバージョンを作成することはできません。
- 最大5つのレイヤーを参照でき、そのうちの1つはオプションでカスタムランタイムにすることができます
サーバーレスアプリケーションの構造
X-RayおよびAmazon CloudWatchの最近の発表
- CloudWatch ServiceLens
- CloudWatch Synthetics
- CloudWatch Logsの埋め込みメトリック形式
- CloudWatch Contributor Insights
- X-Ray Trace Maps
- CloudWatch SyntheticsとのX-Ray統合
機能ごとのLambda同時実行制御
- 同時実行はデフォルトで共有プールです
- 機能ごとの同時実行設定を使用して分離
- 予約として機能します。
- 機能ごとの最大同時実行性としても機能します。
- データベースなどのダウンストリームリソースに特に重要です。
- 「キルスイッチ」-関数ごとの同時実行性をゼロに設定します。
Lambda許可モデル
- Function ポリシー:
- 例:「バケットXのアクションLambda関数Zを呼び出す」
- リソースポリシーはクロスアカウントアクセスを許可します
- 同期および非同期呼び出しに使用
- 実行ロール:
- 例: "Lambda関数AはDynamoDBテーブルユーザーから読み取ります」
- IAMを使用して、この関数がアクセスできるAWSリソース/ API呼び出しを定義します
- ストリーミング呼び出しで使用
サービスアーキテクチャ
今回のマイクロサービスアーキテクチャは、数々のサービスを選定した結果、以下のようになりました。
FIN/ACK- AWS Lambdaを使用したマイクロサービスの構築
Lambdaの特性により、マイクロサービスの構築方法について異なる考え方をすることができます。
- 他の場所に状態を保存する
- APIを実行する3つの方法:Amazon API Gateway、ALB、AWS AppSync
- 4つのストリーム/非同期メソッド:Amazon SNS、Amazon SQS、EventBridge、
- Kinesis Data Streams
- ツールのエコシステムは、多くのことを簡素化します。
- X-Ray
- CloudWatchのメトリクスとログ
- AWS SAM + AWS CloudFormation
- Secrets Manager + パラメーターストア
感想
マイクロサービスの考え方をAWS Lambdaのサーバーレスに落とし込む具体例のセッションでした。LambdaなどのFaaSサービスはマイクロサービスと相性が良いと言われていますが、具体的にどのようにマイクロサービスを構築していくかを具体的なサービスと共に紹介されていたり、このユースケースの場合はこのサービスを使うなどのチートシートなどもあり、とても参考になるセッションでした。