Google App Engine 上でのマイクロサービス アーキテクチャ

マイクロサービスは、アプリケーション開発におけるアーキテクチャ スタイルの 1 つです。マイクロサービスによって、大きなアプリケーションを、それぞれが独自の責任範囲を持つ独立した構成パーツに分解できます。単一のユーザー リクエストまたは API リクエストを受け取ると、マイクロサービスベースのアプリケーションは多くの内部マイクロサービスを呼び出して、レスポンスを作成します。

正しく実装されたマイクロサービスベースのアプリケーションは、以下の目的を達成します。

  • さまざまなマイクロサービスの間に厳密なコントラクトを定義する。
  • 独立したデプロイ サイクル(ロールバックを含む)を可能にする。
  • サブシステム上での A/B リリーステストの同時実行を促進する。
  • テスト自動化と品質保証のオーバーヘッドを最小化する。
  • ロギングとモニタリングの明瞭性を改善する。
  • より詳細な費用計算を提供する。
  • アプリケーションのスケーラビリティと信頼性を高める。

Google App Engine にはマイクロサービスベースのアプリケーションに最適なたくさんの機能があります。ここでは、Google App Engine で実行するマイクロサービスベースのアプリケーションとして自分のアプリケーションをデプロイする際に利用できるおすすめの方法の概略を説明します。

マイクロサービスとしての App Engine サービス

App Engine プロジェクトでは、複数のマイクロサービスを個別のサービス(以前は App Engine で「モジュール」と呼ばれていました)としてデプロイできます。マイクロサービスでは、コードが完全に分離されます。したがって、これらのサービスでコードを実行するには、HTTP 呼び出し(ユーザー リクエストや RESTful API 呼び出しなど)が唯一の方法となります。あるサービスのコードが別のサービスのコードを直接呼び出すことはできません。コードを複数のサービスに別々にデプロイすることが可能で、異なるサービスを異なる言語(Python、Java、Go、PHP など)で作成することもできます。自動スケーリング、負荷分散、マシン インスタンスのタイプはすべてサービスごとに独立して管理されます。

App Engine プロジェクトは、サービスを使用することによって分離を実現します。

サービス内部での複数のバージョン

さらに、それぞれのサービスについて同時に複数のバージョンをデプロイできます。それらのバージョンのうちのいずれか 1 つがそのサービスのデフォルトのバージョンとして機能しますが、サービスの各バージョンはそれぞれ独自のアドレスを持っているので、デプロイされた任意のバージョンに直接アクセスすることが可能です。このような構造のおかげで、新規バージョンのスモークテスト、異なるバージョン間の A/B テスト、ロール フォワードとロールバックの簡易操作など、行えることは限りなく広がります。App Engine フレームワークには、これらの多くを支援するメカニズムが用意されています。それらのメカニズムについては、後のセクションで詳しく説明します。

1 つの App Engine プロジェクトに複数のサービスとバージョンを共存できます。

サービスの分離

サービスどうしはその大部分がそれぞれ分離されているとはいえ、一部の App Engine リソースは共有しています。たとえば、Cloud Datastore、Memcache、タスクキューはみな同じ App Engine プロジェクトに属するサービスの共有リソースです。このような共有にはいくつかの利点がありますが、マイクロサービスベースのアプリケーションにとっては、マイクロサービス間でコードとデータの分離が維持されていることが重要です。不必要な共有による影響を軽減するのに役立つアーキテクチャ パターンがいくつかあります。それらのパターンについては、この記事の後半で説明します。

App Engine プロジェクト同士はサービスを共有します。

プロジェクトの分離

アーキテクチャ パターンに頼って分離を実現するのではなく、もっと秩序に従って分離を強制するには、App Engine プロジェクトを複数作成して使用する方法があります。ここでサービスではなくプロジェクトを利用することには長所と短所があるので、実際の状況を念頭に置いてバランスを考慮する必要があります。複数のプロジェクトを使用することの利点が特に必要とされる状況でない限り、まずは 1 つのプロジェクト内で複数のサービスを使用することから始めるのが最善です。そのほうがパフォーマンスに優れ、管理オーバーヘッドも最低限で済むからです。もちろん、サービスの使用とプロジェクトの使用を融合させた方法も選択できます。

サービスの分離とプロジェクトの分離の比較

次の表に、マイクロサービス アーキテクチャにおいて複数のサービスを使用した場合と複数のプロジェクトを使用した場合の比較を示します。

複数のサービス 複数のプロジェクト
コードの分離 デプロイされるコードは、サービスごと、バージョンごとに完全に独立している。 デプロイされるコードは、プロジェクトごとに完全に独立しており、各プロジェクトのサービスごと、バージョンごとにも完全に独立している。
データの分離 Cloud Datastore と Memcache はすべてのサービスとバージョンで共有されるが、名前空間をデベロッパー パターンとして使用することによりデータを分離できる。タスクキューを分離するには、キュー名のデベロッパー命名規則を利用して、user-service-queue-1 のようにすることができる。 Cloud Datastore、Memcache、タスクキューはプロジェクトごとに完全に独立している。
ログの分離 各サービス(と各バージョン)のログはそれぞれ独立しているが、それらのログを同時に表示することは可能。 各プロジェクト(および各プロジェクトのサービスとバージョン)のログはそれぞれ独立しているが、同一プロジェクトのすべてのログを同時に表示することは可能。ただし、複数のプロジェクトのログを同時に表示することはできない。
パフォーマンスのオーバーヘッド 同一プロジェクトのサービスは同じデータセンターにデプロイされるため、あるサービスが HTTP で別のサービスを呼び出す場合のレイテンシは非常に低い。 プロジェクトがデプロイされるデータセンターはそれぞれ異なる場合があるため、HTTP レイテンシが上がるかもしれないが、Google のネットワークは世界トップレベルなので、上がるとしてもかなり低い。
費用計算 インスタンス時間の費用(コードの実行に要する CPU とメモリ)はサービスごとに分離されない。プロジェクト全体のインスタンス時間すべてが一括で扱われる。 プロジェクトごとの費用は分離されるので、マイクロサービスごとの費用の確認が非常に簡単。
オペレーターの権限 オペレーターは、プロジェクト内のすべてのサービスについて、コードのデプロイ、バージョンのロール フォワードとロールバック、ログの表示を行うことができる。特定のサービスに対するアクセスを制限する方法はない。 プロジェクトごとに個別にオペレーターのアクセスを制御できる。
リクエストのトレース Google Cloud Trace を使用して、同一プロジェクト内のサービスについて、リクエストとその結果生じるマイクロサービスのリクエストを 1 つの合成トレースとして表示できる。この機能のおかげで、パフォーマンス調整が行いやすい。 Cloud Trace 呼び出しは複数のプロジェクトを一括処理できないため、エンドツーエンドのパフォーマンス調整は簡単ではない。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Go の App Engine スタンダード環境