はじめに

マイクロサービスアーキテクチャ(以下MSA)は、互いに協調する複数の小さく独立したサービスで構成されるシステムアーキテクチャです。

MSAは構成する要素技術の中から様々な選択肢を組み合わせて構築します。 例えば、以下のような選択肢があります。

  • サービス間のメッセージのやり取りを同期的に行うか非同期的に行うか
  • 同期的に行う場合HTTPをベースとしたRESTやRPC over HTTPを使うか、HTTPベースではないgRPCを使うか

またMSAの形成/運用補助に必要な技術要素として以下があげられます。

  • サービスディスカバリ
    コンテナ化したアプリケーションを起動した場合、コンテナのIPアドレスは動的に割り当てられます。また、一部のサービスだけをスケールイン/アウトしてコンテナ数を増減させたい場合もあります。増減したコンテナもIPアドレスは動的に割り当てられます。そのような場合に従来のIPアドレスをハードコードする手法ではネットワークを構築できなくなっています。 そのため、MSAではサービスディスカバリと呼ばれるサービス識別子からIPアドレスを解決する手法を取り入れる必要があります。
  • 分散トレーシング
    MSAでは分散したサービス間の関連や性能問題のボトルネック、エラーの原因特定が難しく、解決までに非常に大きなコストがかかります。そのような問題を解決するためにエンドツーエンドでアプリケーションの実行状況をトレースし、ボトルネックやエラーを検出するための分散トレーシングという技術があります。
  • メトリクス収集
    MSAでは必要に応じてサービスをスケールできるよう、CPU負荷やメモリ消費量などのメトリクスを継続的に監視する必要があります。そのため監視対象となるメトリクスを収集する仕組みが必要となります。

弊社フレームワークであるNablarchでも、上記の技術要素を備えたMSAのアプリケーションに対応できるよう、2020年度に機能拡張を行いました。 本記事では、Nablarchに機能拡張をしたポイントと、NablarchでMSAとして開発したアプリケーションをAmazon ECSを使ってFargateで起動しHTTP通信で連携させた例をご紹介します。

※なお本記事ではNablarchとAWSのマネージドサービスを用いてMSAを構築することに主眼を置いています。そのためその他の要素(アプリケーションの冪等性や結果整合性など)については、言及はしていません。

前提

本記事で紹介する内容は以下構成でデモアプリ/環境を作成し、稼働検証した内容となります。

アプリケーションについて

バックエンドのサービスをNablarchのRESTfulウェブサービス実行基盤で作成し、次章で紹介するNablarchの持つMSAを構築するための機能を全て組み込んだアプリケーションを利用しました。 それらを複数サービスとして用意し、互いにHTTPで通信させました。

アプリケーションのビルドに使用するJDKはAdoptOpenJDK 11、Nablarchは5u18を使用しました。

インフラの構成

インフラはAWS上に構築しました。パブリックサブネットとプライベートサブネットを持ち、Amazon ECS クラスターに用意したサービスをAWS Fargateで起動します。

MSAに対応するためのNablarch機能

Nablarchでは、The Twelve-Factor Appに則りMSAを構築する要素として以下の機能を用意しています。

REST API

NablarchのRESTfulウェブサービス実行基盤を使ってREST APIが作成できます。 RESTfulウェブサービスについての解説は以下を参照してください。

コンテナ化

Nablarchではコンテナ化設定済のプロジェクトを生成できるMavenアーキタイプを用意しています。アーキタイプからプロジェクトを生成する方法は以下のガイドを参照してください。

生成したプロジェクトのpom.xmlにはJibを使ったコンテナ化の設定があります。このプロジェクトからコンテナイメージを作成することでTomcatをベースとしたコンテナイメージが作成できます。

環境変数による環境依存値の上書き

The Twelve-Factor AppのIII. 設定では、環境ごとに切り替える設定(連携する他サービスとの接続設定など)は、アプリケーション内部に持たず環境変数から設定すべきとしています。 NablarchではOS環境変数を使って環境依存値を上書きする仕組みを用意しています。コンテナ用アーキタイプから生成したプロジェクトにはこのOS環境変数で環境依存値を上書きする仕組みが設定済となっています。

Redisストア(Lettuce)アダプタ

The Twelve-Factor AppのVI. プロセスでは、アプリケーションはステートレスでなければならないとされています。 セッション情報の保存先にHTTPセッションを使った場合、通常はアプリケーションサーバのメモリ上に状態を持つことになってしまいます。そのため、Nablarchではセッション情報を外部のRedisに保存することでステートレスなアプリケーションとするためのRedisストア(Lettuce)アダプタを提供しています。ステートレスなアプリケーションとすることでスケールイン/アウトを容易に行うことができます 設定方法は以下のガイドを参照してください。

AWS X-Ray SDK for Javaを使った分散トレーシング

AWSではAWS X-Rayというサービスが用意されており、アプリケーションにAWS X-Ray SDKを組み込むことで分散トレーシングが可能となります。

AWS X-Ray SDKをNablarchに組み込む方法は以下のガイドを参照してください。

Micrometerアダプタ

Nablarchでは2020年9月にMicrometerアダプタをリリースしました。このアダプタはMicrometerを使用したメトリクスを収集するためのもので、収集したメトリクスをDatadogAmazon CloudWatchに連携して運用監視を行うことができます。

設定方法は以下のガイドを参照してください。

このアダプタは随時機能拡充を行っており、2021年3月のリリースでは以下のメトリクスを収集できるようにしました。

  • HTTPリクエストの処理時間やパーセンタイルの計測
  • Nablarchバッチのトランザクション単位の処理時間の計測
  • Nablarchバッチの処理件数の計測
  • ログレベルごとの出力回数の計測
  • SQLの処理時間の計測
  • 任意のMbeanから取得した情報をメトリクスとして収集

ヘルスチェックエンドポイントハンドラ

アプリケーションのヘルスチェックを行うためにヘルスチェックエンドポイントハンドラを用意しています。 設定方法は以下のガイドを参照してください。

プロジェクトに合わせて、DBとRedisのヘルスチェックを追加します。

AWSへのデプロイ

上記機能を使って開発したアプリケーションをAWSにデプロイします。

前提

以下のリソースは作成済みとします。

  • プライベートサブネットとパブリックサブネットを持つVPC
  • Application Load Balancer
  • 以下2つのポリシーがアタッチされたコンテナに付与するロール
    • AWSXRayDaemonWriteAccess
    • CloudWatchEventsServiceRolePolicy

Amazon Elastic Container Serviceでサービスを作成する

Amazon Elastic Container Service (Amazon ECS)を利用してサービスを作成します。

1. Amazon Elastic Container Registryにプッシュする

作成したアプリケーションのコンテナイメージをAmazon Elastic Container Registry(Amazon ECR)プッシュします

2. AWS X-Rayデーモンのコンテナイメージをプッシュする

AWS X-Ray SDKが送信したセグメントデータを収集し、X-Rayサービスに中継するため、AWS X-Rayデーモンが必要となります。X-RayデーモンのイメージもAmazon ECRにプッシュします

3. タスクを定義する

タスクを定義します

  • タスクロールには前提に記載したロールを設定します
  • アプリケーションのコンテナイメージを追加します
  • アプリケーションのコンテナ設定では環境変数としてRDSやElastiCacheの接続先を設定します
  • Frontend以外のアプリケーションのタスク定義ではAWS X-Rayデーモンのコンテナイメージもあわせて追加します

X-Rayデーモンはアプリケーションのコンテナにサイドカーとして配置します。そうすることでAWS X-Ray SDKがセグメントデータをX-Rayデーモンに送信し、X-RayデーモンからX-RayのAPIにセグメントデータが中継されます。

4. Amazon ECS クラスターを作成する

Amazon ECS クラスターを作成します。 クラスターの作成手順に従ってネットワークのみのクラスターを作成します。

5. サービスを作成する

コンテナ間の通信はAmazon ECS サービス検出を使用して通信制御を行います。

Amazon ECSサービス検出ではオートスケールやタスク数の増減によってコンテナが増減した場合に、対応するAmazon Route 53のDNSレコードが自動で書き換えられます。これにより、アプリケーションにはホスト名だけを記述し、Amazon Route53が名前解決することでコンテナ間通信ができるようになります。

Amazon ECSクラスター上にタスク定義からAmazon ECS サービスを作成します。

  • 起動タイプには”FARGATE”を選択します
  • VPC、サブネットには予め作成したネットワークのプライベートサブネットを設定します
  • サービスの検出を有効化してサービスの検出サービスを作成します。以下は予め作成した名前空間にサービスを登録するサービスの検出設定例です。

上記のようにサービスを作成すると、サービス検出によって以下のようにAmazon Route53にレコードが自動登録されます。

サービスのタスク数を増やすと以下のようにAレコードが自動的に増えます。

6. 分散トレーシングのサンプリングルールを設定する

X-Ray コンソールでのサンプリングルールの設定を参照してサンプリングルールを設定します。 今回は動作確認のために全てのリクエストをサンプリングしたいので、以下のように設定します。

動作確認

以上でNablarchを使ったMSAの構築が完了しました。ここからは構築した環境の分散トレーシングとメトリクス収集が有効になっていることを確認します。 まずはブラウザで構築したMSAにアクセスします。アプリケーションを操作し、各サービスが正常に動作することを確認します。

AWS X-Ray

AWS X-Rayのコンソールでサービスマップを確認します。サービス間の関連が可視化されています。

個別のトレースについても以下のように詳細表示できます。

Amazon CloudWatch

Amazon CloudWatchでメトリクスを確認します。カスタム名前空間にMicrometerアダプタで設定した名前空間が表示されます。

それぞれの名前空間配下にメトリクスが収集されています。

まとめ

以上がNablarchとAWSのマネージドサービスを用いてMSAを構築する方法になります。

MSAの形成/運用補助に必要な技術要素はそれぞれ以下を組み合わせることで実現できました。

  • サービスディスカバリ
    • AWS
      • Amazon ECSサービス検出
    • Nablarch
      • コンテナ化
      • 環境変数による環境依存値の上書き
  • 分散トレーシング
    • AWS
      • AWS X-Ray
    • Nablarch
      • AWS X-Ray SDKの組み込み
  • メトリクス収集
    • AWS
      • Amazon CloudWatch
    • Nablarch
      • Micrometerアダプタ

今後、Nablarchを使ってMSA開発を行うシステム、プロジェクトに、本ドキュメントに記載した内容が参考になればと思います。