マイクロサービスのフルスタック: 詳細なコアコンポーネントと開発テクニック


簡単に言うと、マイクロサービスとは、独立して実行でき、多くの場合ビジネス機能を中心に構築される小規模な自律サービスのセットとしてアプリケーションを編成する設計アプローチです。これらのサービスは互いに独立して実行され、明確に定義された API を通じて通信します。モノリシック アプリケーションと比較して、マイクロサービス アーキテクチャは柔軟性と拡張性が高く、チームがサービスを独立して開発、デプロイ、拡張できるようになります。

画像-20230915114824429

1. サービスの登録と検出

マイクロサービスの世界では、サービスの登録と検出は、それぞれの独立したサービスが他のサービスを見つけて相互作用できるようにするための重要なメカニズムです。アプリケーションのサイズと複雑さが増大するにつれて、これらのサービス間の相互作用を明確に理解して管理することが重要になります。

1.1. クライアント登録(ZooKeeper)

Apache ZooKeeper は、分散システムの堅固な基盤として、業界で多くの尊敬を集めています。さまざまなマイクロサービス フレームワークを含む多くの分散システムは、命名、構成管理、グループ化サービス、分散同期などの重要なサービスを提供するために ZooKeeper に依存しています。ただし、ここでは、マイクロサービス アーキテクチャにおけるクライアント レジストリとしてのアプリケーションに焦点を当てます。

ZooKeeper の概要
ZooKeeper ダウンロード リンク
ZooKeeper はもともと Yahoo によって作成されましたが、後に Apache のトップレベル プロジェクトになりました。これは分散アプリケーション向けに設計されており、部分的な障害が発生した場合でも分散アプリケーションが動作を継続できる一連のサービスを提供します。これは、小さなコンピューター ノードを接続して強力な分散フレームワークを形成するように設計された ZooKeeper のコア アーキテクチャを通じて実現されます。

ZooKeeperのデータモデル

ZooKeeper のデータ構造は分散ファイル システムによく似ており、ディレクトリとファイルで構成されます。ただし、ZooKeeper では、各ノードは「znode」と呼ばれます。各 znode はデータを保存でき、子ノードを持つことができます。

マイクロサービスが自分自身を登録したい場合、ZooKeeper 内に自分自身の znode を作成します。通常、この znode には、IP アドレス、ポート、その他のメタデータなど、サービスに関する重要な情報が保存されます。

サービス登録の流れ

  1. 起動と接続: マイクロサービスが起動すると、ZooKeeper クラスターへの接続が初期化されます。
  2. Create znode : マイクロサービスは、通常はサービスの名前に基づいて、指定されたパスに znode を作成します。
  3. データの保存: サービスはメタデータをこの znode に保存します。このメタデータには、IP アドレス、ポート、バージョン番号、起動時間などが含まれる場合があります。
  4. 定期的なハートビート: サービスがまだアクティブであることを ZooKeeper に知らせるため、サービスは定期的にハートビートを znode に送信します。
  5. ログアウト: サービスがシャットダウンすると、ZooKeeper 内の znode が削除されます。

【ZooKeeperクライアント登録】

import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;

// 初始化ZooKeeper客户端并注册服务
public class ServiceRegistry {
    
    
    private static final String ZK_ADDRESS = "localhost:2181";
    private ZooKeeper zooKeeper;

    public ServiceRegistry() throws Exception {
    
    
        // 连接ZooKeeper
        this.zooKeeper = new ZooKeeper(ZK_ADDRESS, 5000, watchedEvent -> {
    
    });
    }

    // 注册服务
    public void registerService(String serviceName, String serviceInfo) throws Exception {
    
    
        String path = "/services/" + serviceName;
        if (zooKeeper.exists(path, false) == null) {
    
    
            zooKeeper.create(path, serviceInfo.getBytes(),
            ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
    }
}

// 使用方法:
ServiceRegistry registry = new ServiceRegistry();
registry.registerService("myService", "serviceInstanceInfo");

ZooKeeper の一貫性モデル

ZooKeeper は、データの一貫性を確保するために「Zab」と呼ばれるプロトコルを使用します。Zab プロトコルは、すべての書き込み操作が順序付けされていることを保証します。つまり、複数のノード上のすべての操作が同じ順序で実行されます。

安全性

ZooKeeper は、管理者がどのクライアントがどの操作を実行できるかを制御できる ACL ベースのセキュリティ モデルを提供します。これは、悪意のあるクライアントや設定が間違っているクライアントがシステムに損害を与えるのを防ぐのに役立ちます。

画像-20230915111318244

要約する

ZooKeeper は分散システムの主要コンポーネントとして、マイクロサービス向けに信頼性が高く可用性の高いサービス登録プラットフォームを提供します。その内部の仕組みを理解することで、マイクロサービス アーキテクチャを強化するためにそれをより適切に活用できます。

1.2. サードパーティ登録 (独立したサービス レジストラ)

マイクロサービス アーキテクチャの人気が高まるにつれて、各サービスを直接登録することが複雑になり、時間がかかる場合があります。したがって、これらのサービスの管理を支援するために、サードパーティのサービス登録メカニズム、つまり独立したサービス レジストラを導入する必要があります。

サードパーティ サービス レジストラとは何ですか?

サードパーティ サービス レジストラは、マイクロサービスとサービス登録センターの間の中間層です。マイクロサービスを自動的に検出、登録、登録解除できます。このアプローチでは、各マイクロサービスに直接依存して自身を登録するのではなく、管理と監視のための一元的な場所が提供されます。

なぜサードパーティの登録が必要なのでしょうか?

  1. 自動管理: マイクロサービスが増加すると、サービス インスタンスを手動で登録、更新、登録解除するのが面倒になる場合があります。サードパーティ登録により、これらのタスクを自動的に処理できます。
  2. 集中監視: サードパーティのレジストリを使用すると、開発者と運用チームはすべてのサービスのステータスと正常性を 1 か所で監視できます。
  3. セキュリティの向上: すべての登録および登録解除の操作は中央ポイントを経由するため、登録を許可するサービスをより適切に制御し、悪意のあるサービスの登録を防ぐことができます。

サードパーティ登録の仕組み

  1. サービス検出: レジストラーはネットワークまたは特定のエンドポイントを定期的にスキャンして、新しいサービス インスタンスを見つけます。
  2. サービス登録: 新しいサービス インスタンスが検出されると、レジストラはそれをサービス登録センターに自動的に登録します。
  3. ヘルス チェック: レジストラは、各サービス インスタンスのヘルス チェックを定期的にチェックします。サービス インスタンスが正常でなくなった、またはアクセス不能になったことが判明した場合、そのインスタンスはサービス レジストリから登録解除されます。
  4. メタデータ管理: 追加の構成が必要なサービスの場合、レジストラはこれらのメタデータを保存および管理して、各サービスが期待どおりに実行されるようにできます。

使用するシーン

以下に、サードパーティ サービス レジストラが必要となる可能性のあるいくつかのシナリオを示します。

  • 大規模なデプロイメント: 数百または数千のマイクロサービス インスタンスがある場合、各インスタンスを手動で管理するのは現実的ではありません。
  • 動的環境: クラウド環境では、サービス インスタンスが頻繁に起動およびシャットダウンされる可能性があります。サードパーティの登録により、サービス レジストリが常に最新の状態になります。
  • 高度なセキュリティ要件: 高度なセキュリティ環境では、信頼できるサービスのみが登録できるようにする必要がある場合があります。

課題と考慮事項

  1. ネットワーク オーバーヘッド: サービス インスタンスの健全性を頻繁にチェックする必要があるため、大量のネットワーク トラフィックが生成される可能性があります。
  2. 単一障害点: レジストラー自体に障害が発生すると、すべてのサービスの登録および登録解除の操作に影響が出る可能性があります。

画像-20230915111346338

サードパーティ サービス Registrar を使用すると、マイクロサービスの管理と監視を大幅に簡素化できます。ただし、適切なレジストラ ソリューションを選択して展開するには、それが特定の環境のニーズを満たしていることを確認するための慎重な計画とテストが必要です。

1.3. クライアントの検出

マイクロサービスの世界では、サービス ディスカバリはコア コンポーネントの 1 つです。サービスが別のサービスと対話する必要がある場合、まず他のサービスの場所を知る必要があります。これがサービスディスカバリの目的です。クライアント検出モードでは、呼び出し側サービスは、どのサービス インスタンスと対話する必要があるかを認識する責任があります。

クライアントディスカバリーとは何ですか?

クライアント ディスカバリは、クライアントまたはコンシューマ サービスがネットワーク内で利用可能なサービス インスタンスを特定し、インスタンスと直接通信する役割を担うサービス ディスカバリのパターンです。これは、API ゲートウェイまたはロード バランサーがどのサービス インスタンスと通信するかを決定するサーバー側検出モデルとは対照的です。

クライアント検出の仕組み

  1. 登録: サービス インスタンスが開始されて使用可能になると、そのアドレスがサービス レジストリに登録されます。
  2. クエリ: クライアントがサービスと通信する必要がある場合、クライアントはまずサービス登録センターにクエリを実行して、利用可能なすべてのサービス インスタンスのリストを取得します。
  3. 選択: クライアントは取得したサービスリストから 1 つを選択して通信します。これには通常、ラウンド ロビンやランダム選択など、何らかの形式の負荷分散が含まれます。
  4. 通信: クライアントは、選択したサービス インスタンスと直接通信します。

アドバンテージ

  1. 柔軟性: クライアントは、必要に応じて独自の負荷分散戦略を実装できます。
  2. 待ち時間の短縮: リクエストを処理するための中間コンポーネント (API ゲートウェイやロード バランサーなど) がないため、通信の待ち時間が短縮されます。

欠点がある

  1. クライアントの複雑さ: 各クライアントはサービス検出と負荷分散ロジックを実装する必要があります。
  2. 一貫性の課題: すべてのクライアントは、サービス検出ロジックとポリシーを一貫して更新する必要があります。

クライアント発見のためのツールとテクニック

Eureka、Consul、Zookeeper などの多くのサービス検出ツールは、クライアント検出モードをサポートしています。

  1. Eureka : Netflix によって作成された Eureka は、マイクロサービス アーキテクチャで最も人気のあるサービス検出ツールの 1 つです。Eureka クライアントは組み込みの負荷分散戦略を提供し、Spring Cloud と簡単に統合できます。
  2. Consul : HashiCorp によって開発された Consul は、ヘルスチェック、KV ストレージ、および複数のデータセンターをサポートする多用途のサービス検出ソリューションを提供します。
  3. Zookeeper : 前述したように、Zookeeper は分散調整サービスであり、サービスの検出にもよく使用されます。

画像-20230915111430618

クライアント検出は、マイクロサービスが他のサービスを見つけて通信するための柔軟で低遅延の方法を提供します。ただし、クライアントの複雑さも増し、すべてのクライアントにわたる論理的およびポリシーの一貫性が必要になります。クライアント側の検出を使用するかどうかの選択は、特定のニーズと制約によって異なります。

1.4. サーバー側の検出

サーバー側の検出は、マイクロサービス アーキテクチャにおける一般的なサービス検出パターンです。クライアント側の検出とは対照的に、サーバー側の検出では、サービスを見つける責任がクライアントからサーバーに移されます。

サーバー側の検出とは何ですか?

サーバー側の検出では、クライアント アプリケーションはまず中央のロード バランサーまたは API ゲートウェイにサービスの場所を知るよう要求します。この中心的なコンポーネントは、サービス レジストリにクエリを実行し、サービス インスタンスの場所を特定し、リクエストをそのサービス インスタンスにルーティングします。

サーバー側の検出の仕組み

  1. 登録: クライアント検出と同様に、サービス インスタンスは開始時にその場所をサービス レジストリに登録します。
  2. ルーティングされたリクエスト: クライアントはリクエストをサービス インスタンスに直接送信するのではなく、中央のロード バランサーまたは API ゲートウェイに送信します。
  3. サービス インスタンスの選択: ロード バランサーはサービス レジストリにクエリを実行し、利用可能なサービス インスタンスを見つけて、リクエストをルーティングするインスタンスを決定します。
  4. リクエスト転送: ロード バランサーは、クライアントのリクエストを選択されたサービス インスタンスに転送します。

[ZooKeeper のサービスを発見する]

// 从ZooKeeper中发现服务
public List<String> discoverService(String serviceName) throws Exception {
    
    
    String path = "/services/" + serviceName;
    return zooKeeper.getChildren(path, false);
}

// 使用方法:
List<String> serviceInstances = discoverService("myService");

アドバンテージ

  1. 簡素化されたクライアント: クライアント ロジックはより単純で、中央のロード バランサーの場所を知る必要があるだけです。
  2. 集中トラフィック管理: トラフィック形状、ルーティング、負荷分散ポリシーを中央の場所から管理できます。

欠点がある

  1. レイテンシの増加: リクエストは追加のジャンプを通過する必要があるため、わずかな遅延が発生する可能性があります。
  2. 単一障害点のリスク: 中央のロード バランサーまたは API ゲートウェイに問題がある場合、すべてのリクエストが影響を受ける可能性があります。

画像-20230915111510336

使用するシーン

サーバー側の検出は、モバイル アプリケーション、サードパーティ開発者、または複数のフロントエンド インターフェイスなど、クライアントの多様性が高い環境に特に適しています。

1.5. 領事

Consul は、HashiCorp によって開発されたサービス検出および構成配布ツールです。データセンター全体で高可用性とサポートを提供するように設計されています。

画像

Consulの主な特徴

  1. サービス検出: Consul を使用すると、アプリケーションが他のサービスを提供および検出できるようになり、サービス インスタンスの正常性状態を判断するためのヘルス チェックが提供されます。
  2. Key/Value Store : 構成および動的サービス構成用の分散キー/値ストア。
  3. 複数のデータセンター: Consul は複数のデータセンターをサポートしているため、大規模なアプリケーションに最適です。

コンスルの使い方

  1. インストールと実行: Consul は、公式 Web サイトからダウンロードできる単一のバイナリ ファイルです。これは、各ノード上に Consul エージェントを備えたエージェント モードで実行されます。
  2. サービスの登録:サービス定義ファイルを定義し、コマンドを使用してサービスを登録しますconsul agent
  3. ヘルスチェック: Consul は、さまざまな方法 (HTTP、TCP、指定されたスクリプトの実行など) を通じてサービス インスタンスのヘルス ステータスを定期的にチェックできます。

Consul と他のサービス検出ツールの比較

Eureka、Zookeeper、その他のツールもサービス検出の機能を提供しますが、Consul はマルチデータセンターのサポートやキー/値ストレージなどの独自の機能をいくつか提供します。

1.6. ユーレカ

Eureka は、Netflix がオープンソース化したサービス検出ツールで、特にクラウド環境の大規模分散システムに適しています。その名前は、「私はそれを見つけた!」を意味するギリシャ語に由来しています。

エウレカのコアコンポーネント

  1. エウレカサーバー: サービス登録サービスを提供します。サービスを提供するすべてのクライアント アプリケーションは Eureka に登録し、メタデータ情報を提供する必要があります。
  2. Eureka Client : Eureka サーバーとの対話を簡素化するために使用される Java クライアントです。クライアントにはロード バランサーも組み込まれています。

エウレカの仕組み

  1. サービス登録:エウレカクライアントは起動時に自身の情報をエウレカサーバーに登録し、定期的にハートビートを送信して契約を更新します。
  2. サービス消費: サービス消費者は、Eureka サーバーからレジストリ情報を取得し、ローカルにキャッシュします。消費者はこの情報を使用してサービスプロバイダーを見つけます。
  3. サービスがオフラインになる: クライアントがシャットダウンすると、レジストリ内のインスタンスを削除するように求めるリクエストが Eureka サーバーに送信されます。

エウレカの特徴

  1. 可用性: Eureka は、ネットワークの問題による部分的な障害を非常にうまく処理します。ネットワークの分断によりクライアントがサービスに接続できない場合、クライアントはサーバーの状態をキャッシュし、この情報を使用してリクエストを処理します。
  2. 負荷分散: Eureka クライアントには、サービス インスタンスへのリクエストの負荷分散を提供できるロード バランサーが含まれています。
  3. Spring Cloud との統合: Eureka は Spring Cloud とシームレスに統合できるため、Spring Boot アプリケーションに最適です。

1.7. スマートスタック

SmartStack は Airbnb によって開発されたサービス検出ツールで、Nerve と Synapse という 2 つの主要コンポーネントに基づいています。

神経

Nerve は、各サービス インスタンス上で実行されるように設計されたデーモンです。Zookeeper にサービスを登録する責任があります。サービス インスタンスが異常になった場合、Nerve はそのサービス インスタンスを Zookeeper から登録解除する責任を負います。

シナプス

Synapse は、サービスを検出する必要があるすべてのマシン上で実行されるように設計されたもう 1 つのデーモンです。Zookeeper からサービス登録情報を定期的に取得し、ローカル ロード バランサー (HAProxy など) の構成を更新します。

スマートスタックの機能

  1. 自動ヘルスチェック: Nerve と Synapse が連携して、健全なサービス インスタンスのみがルーティングされるようにします。
  2. 復元力と信頼性: SmartStack は、ネットワークの分断やその他の障害が発生した場合でも、サービスの高可用性を保証します。
  3. 既存のテクノロジーとの統合: Zookeeper を中央ストレージとして、HAProxy をロード バランサーとして使用することで、SmartStack を既存のテクノロジー スタックと簡単に統合できます。

1.8. など

etcd は、オープンソースの可用性の高い分散型キー/値ストアであり、主に共有構成とサービス検出に使用されます。CoreOS によって開発された etcd は、大規模クラスター向けに設計されており、特に Kubernetes に信頼性の高いデータ ストレージを提供します。

etcd のコア機能

  1. 一貫性と高可用性: Etcd は Raft アルゴリズムに基づいており、分散システムにおけるデータの一貫性を確保します。
  2. 分散ロック: etcd を使用して、分散システムのロック メカニズムを実装します。
  3. 監視とアラート: キーと値のペアの変更 (構成の変更やサービスの登録/登録解除など) を監視できます。
  4. シンプルな API : etcd はシンプルな RESTful API を提供し、さまざまなアプリケーションと簡単に統合できます。

etcdの使い方

  1. インストールと起動: バイナリは etcd の GitHub リポジトリからダウンロードできます。etcd が開始されると、クライアント要求のリッスンが開始されます。
  2. キーと値の操作: HTTP API または提供されたコマンド ライン クライアントを使用してetcdctl、ユーザーはキーと値のペアを設定、取得、削除、監視できます。
  3. サービス検出: etcd では、サービス インスタンスは、開始時にアドレスとその他のメタデータをキーと値のペアとして保存します。これらのサービスを必要とするクライアントは、etcd にクエリを実行してサービスを検出できます。

etcd と他のサービス検出ツールの比較

Zookeeper や Consul などのツールと比較して、etcd はよりシンプルで直接的な API を提供します。Kubernetes などの最新のコンテナ クラスターのニーズを満たすように設計されているため、この環境での使用に適しています。

2. APIゲートウェイ

マイクロサービス アーキテクチャでは、API ゲートウェイはサーバーであり、システムのエントリ ポイントであり、リクエストのルーティング、API の構成、負荷分散、認証、承認、セキュリティなどを担当します。画像

API ゲートウェイが必要な理由は何ですか?

API Gateway はサーバーであり、システムに入る唯一のノードとも言えます。これは、オブジェクト指向設計パターンの Facade パターンに非常に似ています。API Gateway は内部システム アーキテクチャをカプセル化し、さまざまなクライアントに API を提供します。また、認可、監視、負荷分散、キャッシュ、リクエストのシャーディングと管理、静的応答処理などの他の機能も備えている場合があります。

  1. 単一の入口: 外部消費者に統一された API 入口を提供し、システムの内部構造を隠します。
  2. API の構成: 複数のマイクロサービスの操作を 1 つの複合操作に結合することで、クライアントとサーバー間のリクエストと応答の数が削減されます。
  3. 負荷分散: 受信リクエストを複数のインスタンスに分散して、システムのスケーラビリティと可用性を向上させます。
  4. セキュリティ: 認証、認可、SSL 処理などの一元的なセキュリティ対策。

APIゲートウェイの共通機能

  1. リクエスト ルーティング: API リクエストを適切なマイクロサービスに転送します。
  2. リクエスト/レスポンス変換: クライアントとサービス間のリクエストとレスポンスの形式を変更します。
  3. API アグリゲーション: 複数のサービスのデータと機能を単一の一貫した API に結合します。
  4. セキュリティ: レート制限、認証、認可が含まれます。
  5. キャッシュ: 一般的なリクエストにキャッシュを提供し、応答時間とその背後にあるサービス負荷を軽減します。

【APIゲートウェイ機能例】

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;

// Spring Cloud Gateway的一个简单配置示例
public class ApiGatewayConfiguration {
    
    
    @Bean
    public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
    
    
        return builder.routes()
            .route(r -> r.path("/service-api/**")
            .uri("http://localhost:8080/"))
            .build();
    }
}

API Gateway は、リクエストの転送、構成、プロトコル変換を担当します。クライアントからのすべてのリクエストは、まず API Gateway を経由してから、これらのリクエストを対応するマイクロサービスにルーティングする必要があります。API Gateway は多くの場合、複数のマイクロサービスを呼び出し、複数のサービスからの結果を集約することによってリクエストを処理します。Web プロトコルと、HTTP プロトコルや WebSocket プロトコルなど、内部で使用される Web 非対応プロトコルとの間で変換できます。以下の図は、現在のアーキテクチャに適合した API ゲートウェイを示しています。

2.1. リクエストの転送

マイクロサービス アーキテクチャでは、リクエスト転送は API ゲートウェイの中核機能の 1 つです。クライアントがリクエストを行った場合、どのサービスがリクエストを処理し、適切なサービス インスタンスに転送するかを決定するのは API ゲートウェイの責任です。

動作原理

  1. 動的ルーティング: 特定のサービスのアドレスをハードコーディングする代わりに、ゲートウェイはルートを動的に決定します。これは通常、前述した Eureka や etcd などのサービス検出メカニズムに基づいています。
  2. 負荷分散: リクエストはサービス インスタンスに転送されるだけでなく、各インスタンスの負荷と正常性が考慮されます。
  3. フィルター チェーン: リクエストを転送する前後に、ゲートウェイはセキュリティ フィルター、応答変換フィルターなどの一連のフィルターを適用できます。

転送戦略

  1. ループ ロビン: 各サービス インスタンスを順番に選択します。
  2. Least Connections : 接続数が最も少ないインスタンスにリクエストを転送します。
  3. レイテンシーを考慮した: 各インスタンスのレイテンシーを考慮して、転送を決定します。
  4. Geolocation : リクエスト ソースの地理的位置に基づいて転送します。

2.2. 応答のマージ

マイクロサービス環境では、クライアント要求により、複数のサービスが連携して最終応答を生成する必要がある場合があります。API ゲートウェイは、複数のサービスからの応答を集約して、統一された一貫した応答をクライアントに提供できます。

使用するシーン

  1. 結合ビュー: たとえば、ユーザーのプロファイル ビューでは、ユーザー サービス、注文サービス、およびレビュー サービスからデータを取得する必要がある場合があります。
  2. 分析とレポート作成: 複数のサービスからデータを集約して、複雑なレポートを生成します。

成し遂げる

  1. 並列リクエスト: API Gateway はリクエストを複数のサービスに並列して送信できるため、全体の応答時間が短縮されます。
  2. データ変換: さまざまなサービスのデータ形式を変換して標準化します。
  3. エラー処理: いずれかのサービスがエラーを返した場合、またはタイムアウトした場合の対処方法を決定します。

2.3. プロトコル変換

テクノロジーの発展に伴い、サービスごとに異なる通信プロトコルが使用される場合があります。API ゲートウェイはプロトコル コンバーターとして機能し、クライアントのリクエストをあるプロトコルから別のプロトコルに変換できます。

  1. HTTP から gRPC : クライアントは HTTP/REST を使用できますが、内部サービスは gRPC を使用します。API Gateway は、これら 2 種類の通信を変換できます。
  2. バージョン変換: 古いクライアントは古い API バージョンを使用している可能性があります。ゲートウェイは、これらのリクエストを新しいバージョンのリクエストに変換できます。

2.4. データ変換

マイクロサービス アーキテクチャでは、歴史的な理由、テクノロジーの選択、またはチームの好みにより、異なるサービスが異なるデータ形式を使用する場合があります。API ゲートウェイはマイクロサービスとクライアントの間の仲介者として機能し、場合によってはデータ形式の変換が必要になります。

使用するシーン

  1. バージョンの互換性: サービスがアップグレードされてデータ形式が変更される場合、古いクライアントが引き続き動作できるようにするために、ゲートウェイは古い形式のデータを新しい形式に変換できます。
  2. 形式の標準化: XML を JSON に変換するか、ベンダー固有の形式を標準形式に変換します。

データ変換戦略

  1. XSLT 変換: XML データの場合、XSLT を使用してデータを変換できます。
  2. JSON 変換: Jackson や Gson などのライブラリを使用して JSON データを変換します。
  3. データ マッピング: ソース データ構造とターゲット データ構造の間のマッピングを定義します。

2.5. セキュリティ認証

API ゲートウェイは、すべての受信リクエストの最初の連絡先であるため、多くの場合、アプリケーションのセキュリティの責任を負います。

主な安全機能

  1. 認証: 要求者が誰であるかを判断します。一般的な方法には、JWT などのトークンベースの認証が含まれます。
  2. 認可: 要求者が実行できる内容を決定します。たとえば、一部のユーザーは読み取りアクセス権しか持たず、他のユーザーは書き込み権限を持つ場合があります。
  3. レート制限: ユーザーまたは IP アドレスに基づいてリクエストのレートを制限し、悪用や攻撃を防ぎます。
  4. ファイアウォール機能: 悪意のある送信元からのリクエストをブロックするか、特定の種類のリクエストをブロックします。

実装戦略

  1. API キー: 各リクエストには API キーが含まれている必要があります。API キーは、ゲートウェイがリクエスタを識別および認証するために使用します。
  2. OAuth : サードパーティのアプリケーションがユーザー アカウントに限定的にアクセスできるようにする標準の認証フレームワーク。
  3. JWT (JSON Web Tokens) : 受信者間の情報の主張を表現するための簡潔で自己完結型の方法。

3. 構成センター

マイクロサービス アーキテクチャでは、構成センターは外部構成を保存するサービスです。外部設定はアプリケーションとは別の設定であり、アプリケーションを再起動せずに変更できます。

なぜ構成センターが必要なのでしょうか?

  1. 動的変更: サービスを再起動せずに、実行時に構成を動的に変更します。
  2. 集中管理: 多数のマイクロサービスを備えた大規模システムの場合、構成の集中管理が必要です。
  3. バージョン管理: 構成の履歴バージョンを保存し、以前のバージョンにロールバックできます。

3.1. Zookeeper 設定センター

Apache ZooKeeper は、分散アプリケーション用の高性能の分散型オープンソース調整サービスです。これは構成管理用に特別に設計されたものではありませんが、このシナリオではよく使用されます。

画像-20230915112147300

ZooKeeper 構成センターの利点

  1. 高可用性: ZooKeeper はその分散型の性質により、高可用性とフォールト トレランスを提供できます。
  2. リアルタイム: 構成が変更されると、関連するサービス インスタンスにリアルタイムで通知できます。
  3. 分散ロック: ZooKeeper は、複数のサービス間で構成を同期するのに役立つ分散ロックをサポートしています。

ZooKeeper を構成センターとして使用する方法

  1. ノードの作成: ZooKeeper では、構成情報を保存するために永続ノードまたは一時ノードを作成できます。一時ノードは、クライアントが切断されると消滅します。
  2. 構成の変更をリッスンする: サービスは、構成ノードの変更をリッスンできます。他のサービスまたは管理者が構成を変更すると、サービスに通知が送られ、構成を再ロードできます。
  3. バージョン管理: ZooKeeper は、各 znode (ZooKeeper のデータ ノード) にバージョン番号を提供します。これは、同時変更による問題を回避するのに役立ちます。

[ZooKeeperから設定を取得]

// 从ZooKeeper获取配置
public String getConfig(String configKey) throws Exception {
    
    
    String path = "/config/" + configKey;
    if (zooKeeper.exists(path, false) != null) {
    
    
        return new String(zooKeeper.getData(path, false, null));
    }
    return null;
}

// 使用方法:
String myConfigValue = getConfig("myConfigKey");

3.2. 構成センターのデータ分類

大規模なマイクロサービス環境では、構成データが膨大になる可能性があるため、効果的に管理および分類する必要があります。

環境ごとに分類

  1. 開発環境: 開発者がローカルで使用する構成。
  2. テスト環境: QA および自動テストに使用される環境。
  3. 本番環境: 実際にユーザーが使用する環境。

サービスごとに分類

マイクロサービスごとに、独自の構成があります。

機能別に分類

たとえば、データベース構成、メッセージ キュー構成、サードパーティ サービス構成などです。

権限とアクセス制御

すべてのサービスまたは個人がすべての構成にアクセスできる必要はありません。構成センターは、許可されたサービスまたは担当者のみが構成を読み取りまたは変更できるようにするために、役割ベースのアクセス制御をサポートする必要があります。

画像-20230915112208695

4. イベントのスケジューリング (Kafka)

Apache Kafka は、リアルタイム、フォールトトレラント、高スループットのデータ ストリーム パイプラインを構築するために使用される分散ストリーム処理プラットフォームです。マイクロサービス アーキテクチャでは、Kafka はイベント駆動型アーキテクチャのコア コンポーネントとしてよく使用されます。

カフカの利点

  1. 高スループット: Kafka は、1 秒あたり数百万のイベントまたはメッセージを処理するように設計されています。
  2. 耐久性: コンシューマが一時的に利用できなくなったりクラッシュしたりしても、メッセージは保存されます。
  3. 分散: Kafka クラスターは複数のマシンに分散して、フォールト トレランスと高可用性を実現できます。

マイクロサービスにおける Kafka のアプリケーション

  1. イベント ソース: トランザクション、監査、または回復の目的で発生するすべてのイベントを記録します。
  2. データ統合: 複数のマイクロサービスからのデータを大規模なデータ ウェアハウスまたはデータ レイクに統合します。
  3. 非同期処理: Kafka を介してプロデューサーとコンシューマーを切り離すことで、非同期処理が可能になります。

[Kafkaを使用してイベントを公開する]

import org.apache.kafka.clients.producer.*;

// Kafka事件发布服务
public class KafkaProducerService {
    
    
    private final Producer<String, String> producer;
    private static final String TOPIC = "event-topic";

    public KafkaProducerService(Properties properties) {
    
    
        this.producer = new KafkaProducer<>(properties);
    }

    public void sendEvent(String key, String value) {
    
    
        producer.send(new ProducerRecord<>(TOPIC, key, value));
        producer.close();
    }
}

// 使用方法:
Properties properties = new Properties();
properties.put("bootstrap.servers", "localhost:9092");
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

KafkaProducerService kafkaService = new KafkaProducerService(properties);
kafkaService.sendEvent("eventKey", "eventValue");

5. サービス追跡 (スタータースルース)

複雑なマイクロサービス環境では、リクエストがさまざまなサービスを介してどのように伝播するかを理解することが重要になります。これは、パフォーマンスの問題を診断し、エラーを追跡し、システムの全体的な動作を最適化するのに役立ちます。それがサービス追跡の目的です。

Spring Cloud Sleuth は Spring Cloud ファミリのコンポーネントであり、Spring Boot アプリケーションにトレースを追加する簡単かつ効果的な方法を提供します。

Spring Cloud Sleuth の仕組み

  1. リクエスト ID : Sleuth は、システムに入るリクエストごとに「トレース ID」と呼ばれる一意の ID を自動的に生成します。この ID は、リクエストとともにシステム全体に伝播されます。
  2. スパン ID : リクエストが新しいサービスに到着するか、新しいアクティビティが開始されるたびに、Sleuth は新しい「スパン ID」を生成します。これは、異なるサービス内の同じリクエストの異なる部分を区別するのに役立ちます。

【Spring Cloud Sleuth配置】

import org.springframework.cloud.sleuth.zipkin2.ZipkinSpanReporter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SleuthConfig {
    
    

    @Bean
    public ZipkinSpanReporter makeZipkinSpanReporter() {
    
    
        return new ZipkinSpanReporter() {
    
    
            @Override
            public void report(zipkin2.Span span) {
    
    
                System.out.println(
                    String.format("Reporting span [%s] to Zipkin", span)
                );
            }
        };
    }
}

このコードは、Zipkin と統合して追跡データを Zipkin に報告するように Spring Cloud Sleuth を構成する方法を示しています。

他のツールと統合する

Spring Cloud Sleuth は、Zipkin、Elasticsearch、Logstash、Kibana (ELK スタック) などのツールと統合して、トレース データを視覚化および分析できます。

6. サービスサーキットブレーカー (Hystrix)

マイクロサービス アーキテクチャでは、1 つのサービスに障害が発生すると、連鎖反応が引き起こされ、システム全体がクラッシュする可能性があります。サービス ヒューズは、電気回路内のヒューズのように機能します。異常な状態が検出されると、さらなる損傷を防ぐために「トリップ」します。

Netflix Hystrix は、最もよく知られたサービスサーキットブレーカーの実装の 1 つです。

ハイストリックスの仕組み

  1. コマンド パターン: Hystrix を使用して、リモート サービスを呼び出すコードを HystrixCommand オブジェクトにカプセル化します。
  2. 分離: Hystrix は、スレッド プールまたはセマフォを通じて各サービス呼び出しを分離し、1 つのサービスの障害が他のサービスに影響を及ぼさないようにします。
  3. サーキット ブレーカー: リモート サービスがしきい値まで継続的に失敗すると、Hystrix は「トリップ」し、サービスへのすべての呼び出しを自動的に停止します。

【Hystrixサーキットブレーカーの例】

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;

public class SimpleHystrixCommand extends HystrixCommand<String> {
    
    

    private final String name;

    public SimpleHystrixCommand(String name) {
    
    
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() throws Exception {
    
    
        // 这里放可能会失败的代码
        return "Hello, " + name + "!";
    }

    @Override
    protected String getFallback() {
    
    
        return "Fallback for: " + name;
    }
}

// 使用方法:
String response = new SimpleHystrixCommand("Test").execute();

6.1. Hystrix サーキットブレーカーのメカニズム

サーキットブレーカーは Hystrix の中心です。その動作原理は、実際の回路ヒューズの動作原理と似ています。

  1. クローズ状態: これは通常の状態であり、すべてのリクエストは正常に処理されます。故障率が所定のしきい値を超えると、回路ブレーカーは「オープン」状態になります。
  2. オープン状態: この状態では、さらなる被害を防ぐために、すべてのリクエストはリモート サービスの呼び出しを試行せずに自動的に失敗します。
  3. 半開状態: 一定時間が経過すると、サーキット ブレーカーは半開状態に移行し、一部のリクエストの通過を許可します。これらの要求が成功すると、サーキット ブレーカーは閉じた状態に戻り、そうでない場合は再び開きます。

これら 3 つの状態により、障害が発生した場合にシステムが迅速に回復できるようになり、同時にリモート サービスが回復するための時間を確保できるバッファも提供されます。

画像-20230915112343517

7. API管理

マイクロサービスのアプリケーションが普及するにつれて、API の数、種類、複雑さが劇的に増加しました。効果的な API 管理は、API のセキュリティ、信頼性、可用性を確保しながら、API の設計、展開、メンテナンス、監視を簡素化することを目的としています。

API 管理のコアコンポーネント

  1. API ゲートウェイ: API のエントリ ポイントとして、リクエストのルーティング、組み合わせ、変換、検証、レート制限などを担当します。
  2. API 設計とドキュメント: 標準化された API 設計ガイドラインのセットを提供し、API ドキュメントを継続的に保守します。
  3. API の監視と分析: API の使用状況、パフォーマンス、エラーを監視し、データに基づいた洞察を提供します。

API管理の課題

  1. バージョン管理: ビジネス ニーズの変化に応じて、API が変更される可能性があります。既存のクライアント管理 API バージョンに影響を与えないようにする方法は重要な考慮事項です。
  2. レート制限とクォータ: 悪用を防止し、公正な使用を確保するには、API に使用制限を設定する必要があります。
  3. セキュリティ: 認証、認可、悪意のある攻撃の防止などを含みます。
  4. 互換性: 既存のユーザーに影響を与えないように、新しい API バージョンには下位互換性がある必要があります。

API 管理のベスト プラクティス

  1. Open API 仕様 (OAS) : OpenAPI などの標準 API 記述形式を使用して、一貫性を確保します。
  2. API テスト: ソフトウェア テストに似ていますが、API のコントラクト、パフォーマンス、セキュリティに重点が置かれています。
  3. API ライフ サイクル管理: 設計から非推奨までの API の完全なライフ サイクルを定義し、このライフ サイクルに従って API を管理します。

マイクロサービス アーキテクチャでは、API 管理が重要なコンポーネントになっています。サービスの数が増えると、効果的な API 管理戦略がなければ、すぐに混乱が生じる可能性があります。上記の方法とツールを通じて、組織は API の健全性、安全性、効率性を確保できます。

【APIフロー制御例】

// 使用Spring Boot Rate Limiter进行API流量控制
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Refill;
import io.github.bucket4j.local.LocalBucketBuilder;

import java.time.Duration;

public class RateLimiterService {
    
    

    private Bucket createNewBucket() {
    
    
        Refill refill = Refill.greedy(10, Duration.ofMinutes(1));
        Bandwidth limit = Bandwidth.classic(10, refill).withInitialTokens(1);
        return LocalBucketBuilder.builder().addLimit(limit).build();
    }

    public boolean tryConsumeToken(Bucket bucket) {
    
    
        return bucket.tryConsume(1);
    }
}

// 使用方法:
RateLimiterService rateLimiter = new RateLimiterService();
Bucket bucket = rateLimiter.createNewBucket();
boolean canProcessRequest = rateLimiter.tryConsumeToken(bucket);
if (canProcessRequest) {
    
    
    // 处理API请求
} else {
    
    
    // 超出限额,拒绝请求或等待
}

上記のコードは、Bucket4j ライブラリを使用して Spring Boot アプリケーションに API のレート制限を実装する方法を示しています。

マイクロサービスのセキュリティも重要な領域です。主な懸念事項には、通信セキュリティ (TLS 暗号化の使用など)、API 認証と認可、データ セキュリティが含まれます。

【APIセキュリティ認証例】

// 使用Spring Security进行API安全认证
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@EnableWebSecurity
public class APISecurityConfig extends WebSecurityConfigurerAdapter {
    
    

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll()
                .antMatchers("/private/**").authenticated()
                .and()
            .httpBasic();
    }
}

上記のコード スニペットは、Spring Security を使用して API パスの基本認証を設定する方法を示しています。/public/以下の API はパブリックですが、/private/以下の API には認証が必要です。

おすすめ

転載: blog.csdn.net/weixin_46703995/article/details/132899828
おすすめ