🚀

精読「AWSで実現するモダンアプリケーション入門」(1)

2025/01/07に公開

AWSで実現するモダンアプリケーション入門
AWSを活用したモダンアプリケーション開発に興味がある方にとって非常に有益な一冊です。初心者から中級者向けにバランスよく解説されており、実践的な知識を得ることができる点が評価できます。

関連記事

モダンアプリケーションとは何か

モダンアプリケーションの定義

モダンアプリケーションとは、アプリケーションの設計、構築、管理を継続的に見直し、変化を受け入れ続ける開発戦略のこと

モダンアプリケーションのベストプラクティス

  • モニタリング
  • サーバレステクノロジー
  • リリースパイプライン
  • モジュラーアーキテクチャ[1]

アプリケーション開発におけるベストプラクティスを適用

The Twelve-Factor App

2012年頃にHeroku社のエンジニアによって提唱されたウェブアプリケーションを実装するためのベストプラクティス

項目 説明
I. コードベース バージョン管理されている1つのコードベースと複数のデプロイ
II. 依存関係 依存関係を明示的に宣言し分離する
III. 設定 設定を環境変数に格納する
IV. バックエンドサービス バックエンドサービスをアタッチされたリソースとして扱う
V. ビルド、リリース、実行 ビルド、リリース、実行の3つのステージを厳密に分離する
VI. プロセス アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する
VII. ポートバインディング ポートバインディングを通してサービスを公開する
VIII. 並行性 プロセスモデルによってスケールアウトする
IX. 廃棄容易性 高速な起動とグレースフルシャットダウンで堅牢性を最大化する
X. 開発/本番一致 開発、ステージング、本番環境をできるだけ一致させた状態を保つ
XI. ログ ログをイベントストリームとして扱う
XII. 管理プロセス 管理タスクを1回限りのプロセスとして実行する

Beyond the Twelve-Factor App

2016年頃にPivotal者のエンジニアによって提唱されたベストプラクティス。The Twelve-Factor Appを尊重しつつ、12種類のプラクティスを更新し、そして新しく3種類のプラクティスを追加し、計15種類のプラクティスから構成されている。

番号 項目 説明
1 One codebase, one application 1コードベース、1アプリケーション
2 API first APIファースト
3 Dependency management 依存関係管理
4 Design, build, release, and run デザイン、ビルド、リリース、実行
5 Configuration, credentials, and code 設定、機密情報、コード
6 Logs ログ
7 Disposability 廃棄容易性
8 Backing services バックエンドサービス
9 Environment parity 環境一致
10 Administrative processes 管理プロセス
11 Port binding ポートバインディング
12 Stateless processes ステートレスプロセス
13 Concurrency 並行性
14 Telemetry テレメトリ
15 Authentication and authorization 認証/認可

コードベース

依存関係

  • 依存関係を宣言する
    The Twelve-Factor Appでは、システム全体にインストールされるパッケージが暗黙的に存在することを認めない。すべての依存関係を厳密に宣言することが重要。

設定

  • 設定コード分離する
    設定とは、環境ごとに異なる値のこと(DB情報[2]、API情報[3]、アプリケーション機能情報[4]、アプリケーション情報[5]等)

  • 設定を外部化する
    AWSでは、AWS systems Manager Parameter Store[6]やAWS Secrets Manager[7]を使うことで、設定を外部化できる。

APIファースト

  • すべてのアプリケーションをAPIにする
    APIのインターフェース仕様があることで、関係者との議論が容易になる

データの取得による状況の可視化

ビジネスデータ

経営陣が将来の計画のために利用したり、マーケティングチームがキャンペーンの効果を測定するために利用されるデータ。(アクティブなユーザー数、新規の会員登録したユーザー数、書籍の販売数、閲覧数、滞在時間など)

重要なのは、これらのデータを取得できるようにモダンアプリケーションが構築されていること。ビジネスの状況を可視化するためにどのようなデータが必要で、必要なデータを取得するためにどのようにアプリケーションを実装し、アーキテクチャを構成するべきかをあらかじめ検討しておく。

運用データ

サービスの運用状況を可視化するために必要なデータ。(運用担当者の呼び出し回数、設定変更など運用作業の依頼として起票されるチケット数、チケットが完了するまでの経過時間、一日あたりのデプロイ数、サービスの可用性等)

システムデータ

インフラやアプリケーションの状況を可視化するために必要なデータ。(リクエスト数、リクエストのエラー数、リクエストの処理時間など)

  • REDメソッド[8]:リクエスト駆動のサービスであれば適応できるメトリクス(特にマイクロサービスアーキテクチャを採用する場合は効果的)
  • USEメソッド[9]:キューとそれを処理するジョブで構成されるようなサービス

オブザーバビリティ(可観測性)

オブザーバビリティとは、「システムの内部で何が起きているのか」を説明できるシステムの能力を示している。すでに紹介したメトリクスに、ログとトレースデータを加え他3本柱という考え方がある。

注目される最新の監視体制「オブザーバビリティ」とは?モニタリングとの違いなどより

サーバーレスやコンテナテクノロジーによる運用改善

サーバーレスとコンテナのワークロード比較

サーバーレスとコンテナの使い分けの1つの指針は「アプリケーション開発に、より多くの時間や人を投資できる選択肢はどれか」という観点で整理する考え方。つまり、Lambdaで要件を満たせない場合[10]にECSやEKSの採用を検討すること。

シナリオによるサーバーレスワークロードの構成例

ユーザーが書籍を購入した後に、会員ページから領収書をPDFファイルとしてダウンロードできる機能

  • 大規模リクエストに対応可能か:SQSの標準キューは1秒あたりほぼ無制限のAPI実行をサポートしているし、Lambda関数も自動的にスケールするため
  • アプリケーションのエラーに対応可能か:SQSの可視性タイムアウト[11]で重複処理を回避
  • 冪等性[12]の考慮ができるか:生成するPDFのファイル名を何かしらの仕様で固定するアプリケーションの工夫で回避
  • モニタリングできるか:SQSのメトリクス(ApproximateAgeOfOldestMessage[13]、ApproximateNumberOfMessagesVisible[14]等)やCloudWatch Logsのログ情報などからモニタリング可能
  • 拡張性があるか:他の下流システムにイベントを連携したい場合、EventBridgeをイベントバスとして利用する

シナリオによるコンテナワークロードの構成例

ポイントの付与や消費、現在のポイント残高や履歴の表示といった機能が必要。将来の拡張性を考慮し、ポイント機能をAPIとして提供する。

  • 大規模リクエストに対応可能か:APIはElastic Load Balancingを経由しているため、問題ない。また、Auto Scalingを利用することでECSで実行するコンテナアプリケーションの数を自動で増減できる
  • アプリケーションのエラーに対応可能か:APIのレスポンスにエラー情報が含まれるため、クライアント側で適切なエラーハンドリングを実装できる
  • 冪等性の考慮ができるか:ポイント付与や消費等の更新処理において、APIリクエストに購入IDのような購入情報を一意に特定するパラメーターを定義し、DB側でそれらをプライマリキーに設定することで、ポイントの更新処理を冪等な操作にできる
  • モニタリングできるか:Elastic Load BalancingのApplication Load BalancerはREDメソッドメソッドのメトリクスがCloudWatchメトリクスに発行される。また、CloudWatch Container Insightsを利用すれば、これらのメトリクスから問題を検知した場合に調査するためのデータとして、詳細なリソースメトリクスを取得できる。さらに、CloudWatch Logsやのログ集約やX-Rayを利用したトレーシングデータの集約なども取得可能
  • 拡張性があるか:ポイント機能はAPIとして提供するため、APIの実処理を行うアプリケーション部分は必要に応じて再構成が可能。(例.APIのインターフェイスは維持し、バックエンドをコテなからサーバレスに置き換えられる)

CI/CDパイプラインによるデリバリーの自動化

CI/CDパイプラインに必要となる機能

要件にあったデータベースの選択

データベースに求める機能と要件

  • データ量:データサイズやデータ件数
  • データ増減パターン:大きく増減するのか
  • 保持期間:いつまで保持する必要があるのか
  • アクセスパターン:参照、追加、更新、削除など。(Read Heavy?Write Heavy?)
  • 形式:保存するデータの種類や形式(リレーショナル、キーバリュー、インメモリ、ドキュメント、ワイドカラム、グラフ、時系列、台帳)

Purpose-built databaseとは何か?

データベースの選択は、「データベースXはアプリケーションで実現したい要件に最適だから」という理由で選択すべき。

Purpose-built databases: The model for building applications in the cloudより

シナリオによるデータベースの選択

  • 書籍データ:書籍データには多くの決まった情報があり、他のデータと紐づけて検索をすることもあるため、RDSが最適。さらに、アクセスパターンとして参照が多くなるパターンであると想定されるため、ElastiCacheも組み合わせて使う
  • お気に入りデータ:レコードが大量になる可能性があるので、データ量の観点でスケーラビリティ性に強みのあるDBが良さそう。また、データサイズも少なめなため(ユーザーID、書籍ID、タイムスタンプ)、DynamoDBが最適。
    • お気に入り登録、削除は プライマリーキーを設定してアイテムの操作(PutItem,GetItem,DeleteItem等)をすれば実現できる
    • もう少し自由に操作したい場合、セカンダリインデックス[15]を使う。


Amazon DynamoDBとは何かをわかりやすく図解、どう使う?テーブル設計の方法とはより

参考


https://dev.classmethod.jp/articles/sqs-visibility-timeout/

脚注
  1. モジュラーモノリス、マイクロサービス等 ↩︎

  2. エンドポイント、アカウント、データベース名など ↩︎

  3. エンドポイント、パラメータなど ↩︎

  4. ポイント付与率、表示項目数、フィーチャーフラグなど ↩︎

  5. ログレベルなど ↩︎

  6. 設定を一元的に管理できる機能 ↩︎

  7. アプリケーションなどに必要なシークレット情報の保護を支援するサービス ↩︎

  8. リクエスト数、リクエスト数、リクエストのエラー数、リクエストの処理時間の頭文字 ↩︎

  9. タスクの処理件数、キューイングされているタスクの件数、エラー件数の頭文字居 ↩︎

  10. Lambda関数のタイムアウト設定は最大で15分なので、それ委譲の実行時間が想定されるアプリケーションでは採用が難しくなる ↩︎

  11. 可視性タイムアウトとは、 SQS のキューに入ったメッセージが処理開始直後に重複して処理されないように、処理中の場合、一時的に他のプロセスからは、メッセージが存在していることを見えないようにする設定 ↩︎

  12. ある操作を1回行っても複数回行っても結果が同じであることをいう概念 ↩︎

  13. キューの中で最も古い削除されていないメッセージのおおよその経過期間 ↩︎

  14. キューの中で取得可能なメッセージのおおよその件数 ↩︎

  15. ローカルセカンダリインデックス(LSI)、グローバルセカンダリインデックス(GSL) ↩︎

Discussion