私は 2015 年に Docker ベースのコンテナ テクノロジーに触れ始めました。2 年以上にわたり、Docker DevOps 実践者として、Docker の技術システムの急速な発展も目の当たりにしました。この記事では主に企業内で構築されるマイクロサービスアーキテクチャの実践プロセスをもとに簡単にまとめています。ビジネスを開始する初期段階でサービス アーキテクチャ システムをレイアウトする方法を検討している、またはエンタープライズ レベルのアーキテクチャについて予備的な理解を求めている DevOps 学生に何らかの参考になれば幸いです。
スタートアップの技術的なレイアウトに関しては、基本的にスタートアップは迅速にオンライン化して迅速に試行錯誤する必要があるという声が多い。単一のアプリケーションを使用するか、フロントエンド アプリケーションとバックエンド アプリケーションを分離して、迅速に統合、開発、リリースします。しかし実際には、この結果によって生じる隠れたコストはさらに高くなります。ビジネスが発展し、開発者が増えると、巨大なシステムの導入効率や開発協力の効率が課題になります。そして、サービスの分割、データの読み書き、サブデータベースとサブテーブルの分離によって構造を再構築します。また、この方法を徹底しようとすると、多大な労力と物的リソースが必要になります。
私の個人的な提案は、DevOps はビジネスの現在および長期的な開発に関する独自の判断に基づいて行われるべきであり、プロジェクトの初期段階でマイクロサービス アーキテクチャを使用でき、それが将来の世代に利益をもたらすということです。
Docker を中心としたオープンソース コミュニティの発展により、マイクロサービス アーキテクチャの概念はより良い実装計画を持つことができます。また、各マイクロサービス アプリケーション内では、DDD (Domain-Drive Design) のヘキサゴナル アーキテクチャをインサービス設計に使用できます。 DDD に関するいくつかの概念については、以前に書かれたいくつかの記事も参照できます: ドメイン駆動設計の組織 - 概念とアーキテクチャ、ドメイン駆動設計の組織 - エンティティと値オブジェクトの設計、ドメイン サービス、ドメイン イベント。
明確なマイクロサービス ドメイン分割、サービス内のアーキテクチャ レベルのエレガントな実装、RPC またはイベント ドリブンを介したサービス間で必要な IPC、すべてのマイクロサービスのリクエスト転送に使用される API ゲートウェイ、およびノンブロッキングのリクエスト結果のマージ。以下の記事では、上記の特徴を持つマイクロサービスアーキテクチャをDockerを使って分散環境で素早く構築する方法を詳しく紹介します。
Docker テクノロジーを使用してマイクロサービス システムを構築する場合、サービス検出は避けられないトピックになります。現在、主流のサービス検出モードには、クライアント検出モードとサーバー検出モードの 2 つがあります。
クライアント発見モード
クライアント発見モードのアーキテクチャ図は次のとおりです:
クライアント発見モードの典型的な実装は、Netflix システムテクノロジーです。クライアントは、サービス登録サービス センターから利用可能なすべてのサービス インスタンスを照会します。クライアントは負荷分散アルゴリズムを使用して、複数の利用可能なサービス インスタンスから 1 つを選択し、リクエストを行います。典型的なオープンソース実装は、Netflix の Eureka です。
Netflix-Eureka
Eureka のクライアントは自己登録モードを採用しており、サービス インスタンスの登録と登録解除の処理、およびハートビートの送信を行う必要があります。
SpringBootを利用してマイクロサービスを統合する場合、SpringCloudプロジェクトと組み合わせることで簡単に自動登録が実現できます。 @EnableEurekaClient をサービス起動クラスに追加して、サービス インスタンスの起動時に構成済みの Eureka サーバーにサービスを登録し、ハートビートを定期的に送信します。クライアント側の負荷分散は、Netflix リボンによって実装されます。サービス ゲートウェイは Netflix Zuul を使用し、サーキット ブレーカーは Netflix Hystrix を使用します。
サービス検出のサポート フレームワークに加えて、SpringCloud の Netflix-Feign は、サービスの REST リクエストを処理するための宣言型インターフェイスを提供します。もちろん、FeignClient を使用するだけでなく、Spring RestTemplate を使用することもできます。プロジェクトで @FeignClient を使用すると、コードが読みやすくなり、Rest API が一目で明確になります。
サービスインスタンスの登録管理やクエリはすべてアプリケーション内でEurekaが提供するREST APIインターフェースを呼び出すことで行われます(もちろんSpringCloud-Eurekaを使用する場合はこの部分のコードを記述する必要はありません)。サービスの登録と登録解除はクライアント自体を通じて要求されるため、このモデルの大きな問題は、異なるプログラミング言語に対して異なるサービスが登録されることになり、サービス検出ロジックを開発言語ごとに個別に開発する必要があることです。さらに、Eureka を使用する場合は、ヘルスチェックのサポートを明示的に構成する必要があります。
サーバー側検出モード
サーバー側検出モードのアーキテクチャ図は次のとおりです:
クライアントはリクエストをロードバランサーに送信し、ロードバランサーはリクエストをサービスレジストリに送信し、レジストリで使用可能なサービスにリクエストを転送します。サービス インスタンスもレジストリに登録および登録解除されます。負荷分散には Haproxy または Nginx を使用できます。 Docker に基づくサーバー側検出モードの現在の主流ソリューションは、Consul、Etcd、および Zookeeper です。
Consul
Consul は、クライアントがサービスを登録および検出できるようにする API を提供します。その一貫性は RAFT アルゴリズムに基づいています。 WAN のゴシップ プロトコルを介してメンバーとブロードキャスト メッセージを管理し、データセンター間の同期を完了し、ACL アクセス制御をサポートします。 Consul はヘルス チェック メカニズムも提供し、kv ストレージ サービスをサポートします (Eureka ではサポートされていません)。 Consul のより詳細な紹介については、以前に書いた記事「Consul クラスターの Docker コンテナーのデプロイメント」を参照してください。
Etcd
Etcd は強整合性 (CAP を満たす CP) であり、可用性が高くなります。 etcd も RAFT アルゴリズムに基づいており、KV データ同期の強力な一貫性を実現します。 Kubernetes は Etcd の KV 構造を使用して、すべてのオブジェクトのライフサイクルを保存します。
Etcd の一部の内部原則については、etcd v3 の原則分析をご覧ください
Zookeeper
ZK は、Hadoop で初めて使用されました。そのシステムは非常に成熟しており、大企業でよく使用されています。すでに独自の ZK クラスターをお持ちの場合は、ZK を独自のサービス登録センターとして使用することを検討できます。
Zookeeper は Etcd と同じで、強い一貫性と高可用性を備えています。コンセンサス アルゴリズムは Paxos に基づいています。マイクロサービス アーキテクチャの初期段階では、サービス検出に重い ZK を使用する必要はありません。
サービス レジストリは、サービス検出における重要なコンポーネントです。 Kubernetes と Marathon に加えて、それらのサービス検出は組み込みモジュールです。サービスはレジストリに登録する必要があります。上記で紹介した Eureka、consul、etcd、ZK はすべてサービス レジストリの例です。
マイクロサービスをレジストリに登録する方法には、自己登録モードとサードパーティ登録モードという 2 つの一般的な登録方法があります。
セルフ登録パターン
上記の Netflix-Eureka クライアントは、セルフ登録パターンの典型的な例です。つまり、各マイクロサービス インスタンス自体がサービスの登録と登録解除を行う必要があります。 Eureka は、登録情報の正確性を確保するためのハートビート メカニズムも提供しており、マイクロサービスの SpringBoot で特定のハートビート送信間隔を構成できます。
以下のように、Eureka をレジストリとして使用する場合、マイクロサービス (SpringBoot アプリケーション) の開始時にサービス登録情報が存在します:
同様に、アプリケーションが非アクティブ化された場合、サービス インスタンスはアクティブにログアウトする必要があります。インスタンス情報 :
自己登録メソッドは、追加の機能やエージェントを必要とせず、マイクロサービス インスタンス自体がサービスの登録を管理します。しかし、欠点も明らかです。たとえば、Eureka は現在 Java クライアントのみを提供しているため、多言語マイクロサービスの拡張には不便です。マイクロサービスはサービス登録ロジック自体を管理する必要があるため、マイクロサービス実装ではサービス登録とハートビート メカニズムも結合します。言語間のパフォーマンスは比較的悪いです。
ここで皆さんに建築学習交流グループをお勧めします。コミュニケーションおよび学習グループ番号: 478030634。上級アーキテクトによって記録されたいくつかのビデオを共有します: Spring、MyBatis、Netty ソース コード分析、高同時実行性の原則、高性能、分散、マイクロサービス アーキテクチャ、JVM パフォーマンスの最適化、分散アーキテクチャなど。建築家にとって必須の知識体系となっています。無料の学習リソースも受け取ることができ、現在多くの恩恵を受けています
サードパーティ登録、つまり、専任のサービスマネージャー (Registar) によるサービス登録 (登録、キャンセルサービス) の管理が来ます。指揮を取る。 Registrator は、オープンソースのサービス マネージャー実装です。 Registrator は、Etcd および Consul のレジストリ サービス サポートを提供します。レジストレーターは、プロキシ サービスとして、マイクロサービスが配置されているサーバーまたは仮想マシン上にデプロイして実行する必要があります。より簡単なインストール方法は、Docker を介してコンテナーとして実行することです。
スリーパーティ登録モデルのアーキテクチャ図は次のとおりです:
サービス マネージャーを追加することにより、マイクロサービス インスタンスは登録センターに直接登録したり、登録センターにログアウトしたりしなくなります。サービス マネージャー (Registar) は、サービスのサブスクライブ、ハートビートの追跡、登録センター (consul、etcd など) への登録、インスタンスの登録解除、ハートビートの送信によって、利用可能なサービス インスタンスを検出します。このようにして、サービス ディスカバリ コンポーネントとマイクロサービス アーキテクチャの分離を実現できます。
Registrator は Consul および Consul Template と協力してサービス ディスカバリ センターを構築します。スケーラブル アーキテクチャ DR CoN: Docker、Registrator、Consul、Consul Template、および Nginx を参照してください。この記事では、負荷分散に Nginx を使用する例を示します。特定の実装プロセスでは、代わりに Haproxy または他のソリューションを使用することもできます。
上記のサービス検出テクノロジーに加えて、Kubernetes には、サービス インスタンスの登録と登録解除の処理を担当する独自のサービス検出モジュールが付属しています。また、Kubernetes は各クラスター ノードでエージェントを実行し、ルーターのサーバー側検出を実装します。オーケストレーション テクノロジで k8n を使用する場合は、k8n の Docker マイクロサービス ソリューションの完全なセットを使用できます。k8n に興味がある人は、Kubernetes アーキテクチャの設計と基本原則を読むことができます。
実際のテクノロジー選択において最も重要なことは、ビジネスやシステムの将来の発展特性に基づいて合理的な判断を下すことです。
CAP理論において。 Eureka は AP、Consul は CA、ZK と Etcd は CP を満たします。 Eureka と Consul は両方とも、分散シナリオでの可用性を保証できます。小規模なサーバー インスタンスを使用する場合、Eureka を使用すると、追加の高可用性サービス登録センターを構築する必要がないため、比較的迅速に Eureka サービスを構築できます。
Eureka と Consul は両方とも、サービス登録データを表示できる WebUI コンポーネントを提供します。 Consul は KV ストレージも提供し、http および DNS インターフェイスをサポートします。スタートアップが最初にマイクロサービスを構築する場合は、この 2 つが推奨されます。
マルチデータセンターに関しては、Consul にはデータセンター WAN ソリューションが付属しています。 ZK も Etcd もマルチデータセンター機能をサポートしていないため、追加の開発が必要です。
クロスランゲージの観点では、Zookeeper が提供するクライアント API を使用する必要があり、クロスランゲージのサポートは弱いです。 Etcd と Eureka は両方とも http をサポートし、Etcd は grpc もサポートします。 http に加えて、Consul は DNS サポートも提供します。
セキュリティの面では、Consul と Zookeeper は ACL をサポートし、Consul と Etcd はセキュア チャネル HTTPS をサポートします。
SpringCloud は現在、Eureka、Consul、Etcd、および ZK を対応するサポートを提供しています。
Consul は Docker と同様に Go 言語で実装されており、Go 言語に基づくマイクロサービス アプリケーションは Consul の使用を優先できます。
マイクロサービスアーキテクチャシステムに従ってサービス発見の問題を解決した後。サービス間の適切な通信メカニズムを選択する必要があります。 SpringBoot アプリケーションを使用している場合、HTTP プロトコルに基づく REST API の使用は同期ソリューションです。さらに、Restful スタイルの API により、各マイクロサービス アプリケーションをよりリソース指向にすることができ、軽量プロトコルの使用もマイクロサービスによって提唱されています。
各マイクロサービスが DDD (ドメイン駆動設計) のアイデアを使用している場合、各マイクロサービスは同期 RPC メカニズムを使用しないようにする必要があります。 AMQP や STOMP などの非同期メッセージベースのメソッドは、マイクロサービス間の依存関係を疎結合するのに適しています。現在、メッセージベースのポイントツーポイント パブリッシュ/サブスクライブ フレームワークには多くのオプションがあります。以下に、2 つの IPC のいくつかのソリューションを詳しく紹介します。
同期
同期リクエスト/レスポンスモード通信用。 Restful スタイルの Http プロトコル、または優れた言語間機能を備えた Thrift プロトコルに基づくサービス間の通信を選択できます。 Pure Java 言語マイクロサービスを使用している場合は、Dubbo を使用することもできます。 SpringBoot と統合されたマイクロサービス アーキテクチャ システムの場合は、優れた言語間パフォーマンスと Spring コミュニティからのサポートが充実した RPC を選択することをお勧めします。
Dubbo
Dubbo は、Alibaba によって開発されたオープンソースの Java クライアント RPC フレームワークです。 Dubbo は、TCP プロトコルの長い接続に基づいてデータを送信します。転送形式はヘシアン バイナリ シリアル化を使用します。サービス登録センターは、Zookeeper を通じて実装できます。
ApacheThrift
ApacheThrift は Facebook によって開発された RPC フレームワークです。コード生成エンジンは、C++、Java、Python、PHP、Ruby、Erlang、Perl などの複数の言語で効率的なサービスを作成できます。送信されるデータはバイナリ形式であり、Json 形式や XML 形式を使用した HTTP プロトコルよりもパケットサイズが小さくなります。ビッグデータのシナリオでは、同時実行性が高い方が有利です。
Rest
Rest は HTTP プロトコルに基づいており、HTTP プロトコル自体には豊富なセマンティクスがあります。 Springboot が広く使用されるにつれて、Restful スタイルの API がますます普及してきています。 REST は HTTP プロトコルに基づいており、ほとんどの開発者は HTTP に精通しています。
ここでもう 1 つ言及すべき点は、多くの企業やチームも Springboot を使用しており、それらは Restful スタイルに基づいているとも述べていることです。しかし現実には、導入が進んでいないことが多いのです。あなたの Restful が本当に Restful であるかどうかを確認するには、この記事を参照してください。この記事では、Restful スタイルの API の成熟度を 4 つのレベルで分析しています: Richardson 成熟度モデルは、REST の栄光に向けて一歩を踏み出します。
Springboot を使用する場合、どのようなサービス検出メカニズムが使用されているかに関係なく、Spring の RestTemplate を使用して基本的な Http リクエストのカプセル化を行うことができます。
上記のNetflix-Eurekaを使用している場合は、Netflix-Feignを使用できます。 Feign は宣言型 Web サービス クライアントです。クライアント側の負荷分散には Netflix-Ribbon を使用します。
非同期
純粋な「イベント駆動型アーキテクチャ」を除く、マイクロサービス アーキテクチャでは、メッセージ キューを使用するシナリオは一般に、マイクロサービスを分離することです。サービスは、どのサービス インスタンスがメッセージを消費または公開するかを知る必要はありません。独自のドメイン内でロジックを処理し、メッセージ チャネルを通じて公開するか、関心のあるメッセージを購読するだけです。現在、オープン ソースのメッセージ キュー テクノロジが多数存在します。たとえば、Apache Kafka、RabbitMQ、Apache ActiveMQ、Alibaba の RocketMQ は、現在 Apache プロジェクトの 1 つになっています。メッセージ キュー モデルでは、次の 3 つの主要コンポーネントがあります:
プロデューサー: メッセージを生成し、チャネルにメッセージを書き込みます。
メッセージ ブローカー: メッセージ ブローカーは、キューの構造に従ってチャネルに書き込まれるメッセージを管理します。メッセージの保存/転送を担当します。ブローカーは通常、個別に構築および構成する必要があるクラスターであり、高可用性が必要です。
コンシューマ: メッセージのコンシューマ。最新のメッセージ キューでは、メッセージが少なくとも 1 回は消費されることが保証されています。したがって、使用されるメッセージ キュー機能に応じて、コンシューマは冪等である必要があります。
メッセージ キューの実装が異なれば、メッセージ モデルも異なります。各フレームワークの特性も異なります。
RabbitMQ
RabbitMQ は、高いパフォーマンスとスケーラビリティで有名な Erlang で書かれた AMQP プロトコルに基づくオープンソース実装です。現在、クライアントは Java、.Net/C#、Erlang をサポートしています。 AMQP (Advanced Message Queuing Protocol) コンポーネントのうち、Broker には複数の Exchange (スイッチ) コンポーネントを含めることができます。 Exchange は、他の Exchange と同様に複数のキューをバインドできます。メッセージは、Exchange で設定されたルーティング ルールに従って、対応するメッセージ キューに送信されます。 Consumer はメッセージを消費した後、Broker との接続を確立します。消費されたメッセージの通知を送信します。その後、Message Queue によってメッセージが削除されます。
Kafka
Kafka は、高性能のパブリッシュ/サブスクライブ ベースの言語を超えた分散メッセージング システムです。 Kafka の開発言語は Scala です。より重要な機能は次のとおりです。
時間計算量が O(1) の高速メッセージ永続性
メッセージの順次送信を保証しながら、サービス間のメッセージ分割と分散消費をサポートします。負荷分散;
消費のみおよび 1 回のみ (Exactly Once) モードなどをサポートします。
欠点について話しましょう: 管理インターフェイスは少し役に立ちません。オープンソースの kafka-manager を使用できます。その高いスループット特性により、マイクロサービス間のメッセージ キューとしてだけでなく、ログ収集にも使用できます。オフライン分析とリアルタイム分析の待機。
Kafka はクライアント API の Java バージョンを正式に提供しており、Kafka コミュニティは現在、PHP、Python、Go、C/C++、Ruby、NodeJS などを含む複数の言語をサポートしています。
ActiveMQ
ActiveMQは、JMS(Java Messaging Service)をベースに実装されたJMSProviderです。 JMS は主に、ポイントツーポイントとパブリッシュ/サブスクライブの 2 種類のメッセージを提供します。現在、クライアントは Java、C、C++、C#、Ruby、Perl、Python、および PHP をサポートしています。また、ActiveMQ は、Stomp、AMQP、MQTT、OpenWire などの複数のプロトコルをサポートしています。
RocketMQ/ONS
RocketMQ は、Alibaba によって開発されたオープンソースの高可用性分散メッセージ キューです。 ONS は、商用バージョンを提供する高可用性クラスターです。 ONS はプル/プッシュをサポートします。アクティブなプッシュと数百億のメッセージの蓄積をサポートできます。 ONS はグローバルな順次メッセージをサポートし、メッセージ キューの消費を監視し、複数のメッセージ再送信の手動トリガーをサポートする使いやすい管理ページを備えています。 まとめ
API Gateway を使用してマイクロサービスリクエストの転送とマージを処理します
前のセクションでは主に、マイクロサービスのサービス検出と通信の問題を解決する方法を紹介しました。マイクロサービス アーキテクチャ システムでは、DDD の考え方を使用してサービス間で境界のあるコンテキストを分割すると、マイクロサービス間の呼び出しが最小限に抑えられます。マイクロサービスを分離するために、API ゲートウェイに基づく最適化ソリューションがあります。
分離されたマイクロサービス呼び出し
たとえば、次は一般的な需要シナリオです - 「ユーザー注文リスト」の集計ページです。基本的なユーザー情報を取得するには「ユーザーサービス」をリクエストし、注文情報を取得するには「注文サービス」をリクエストし、注文リスト内の製品の写真やタイトルなどの情報を取得するには「製品サービス」をリクエストする必要があります。以下の図に示すように:
クライアント (H5、Android、iOS など) が複数の情報集約を解決するために複数のリクエストを発行できる場合、クライアントの複雑さが増加します。より合理的な方法は、API ゲートウェイ レイヤーを追加することです。マイクロサービスと同様に、API Gateway も Docker コンテナーでデプロイして実行できます。これは Springboot アプリケーションでもあります。以下のように、ゲートウェイ API を介して転送した後:
要求されたすべての情報は、システムに入る唯一のノードでもあるゲートウェイによって集約されます。また、ゲートウェイとすべてのマイクロサービスは、クライアントに提供されるだけでなく、Restful スタイルの API です。ゲートウェイ層の導入により、情報集約の問題は十分に解決できます。たとえば、H5 ページではユーザー情報を表示する必要がなく、リソースをリクエストするためにゲートウェイ API を追加するだけで済みます。マイクロサービス層を表示する必要はありません。変更は必要ありません。
API Gatewayはリクエストをマージして転送するだけではありません。完全なゲートウェイになるには他の機能も必要です。
レスポンシブ プログラミング
ゲートウェイは、すべてのクライアント リクエストのエントリ ポイントです。ファサード モードに似ています。リクエストのパフォーマンスを向上させるには、ノンブロッキング I/O フレームワークを選択するのが最善です。複数のマイクロサービスを要求する必要がある一部のシナリオでは、各マイクロサービスの要求を必ずしも同期する必要はありません。上記の「ユーザー注文リスト」の例では、ユーザー情報の取得と注文リストの取得は 2 つの独立したリクエストです。注文の商品情報を取得する場合のみ、注文情報が返されるのを待ってから、注文の商品 ID リストに基づいて商品マイクロサービスをリクエストする必要があります。リクエスト全体の応答時間を短縮するには、ゲートウェイが独立したリクエストを同時に処理できる必要があります。解決策の 1 つは、リアクティブ プログラミングを採用することです。
Java テクノロジー スタックを使用した現在のリアクティブ プログラミング メソッドには、Java8 の CompletableFuture と、ReactiveX によって提供される JVM ベースの実装 (RxJava) が含まれます。
ReactiveX は、観察可能なデータ ストリームを使用した非同期プログラミング用のプログラミング インターフェイスであり、オブザーバー パターン、イテレーター パターン、および関数型プログラミングの本質を組み合わせています。 RxJava に加えて、RxJS や RX.NET などの多言語実装もあります。
ゲートウェイの場合、RxJava が提供する Observable は並列独立 I/O リクエストを非常にうまく解決できます。マイクロサービス プロジェクトで Java8 が使用されている場合、チーム メンバーは RxJava の機能をより早く学習し、吸収することができます。 Lambda スタイルにも基づく応答性プログラミングにより、コードをより簡潔にすることができます。 RxJava の詳細については、RxJava のドキュメントとチュートリアルを参照してください。
リアクティブ プログラミングのオブザーバブル モードを通じて、イベント ストリームとデータ ストリームを簡単かつ便利に作成し、単純な関数を使用してデータを結合および変換することができます。同時に、任意のオブザーバブル データ ストリームをサブスクライブして操作を実行できます。
RxJava を使用することにより、「ユーザー順序リスト」のリソース要求シーケンス図:
レスポンシブ プログラミングは、さまざまなスレッドの同期と同時要求をより適切に処理でき、Observable と Scheduler のスレッド処理を通じて透過的なデータ フローとイベント フローを提供します。アジャイル開発モデルでは、リアクティブ プログラミングによりコードがより簡潔になり、保守が容易になります。
認証
ゲートウェイはシステムへの唯一の入り口であり、マイクロサービスに基づくすべての認証はゲートウェイを中心に実行できます。 Springboot プロジェクトでは、基本認証に spring-boot-starter-security および Spring Security を使用できます (Spring Security は Spring MVC プロジェクトに統合することもできます)。
Spring Security は主に AOP を使用してリソースリクエストをインターセプトし、ロールのフィルターチェーンを内部的に維持します。マイクロサービスは Gateway を通じて要求されるため、Gateway のさまざまなリソースのロール レベルに応じてマイクロサービスの @Secured を設定できます。
Spring Security は、基本的なロール検証インターフェイス仕様を提供します。ただし、クライアントが要求したトークン情報の暗号化、保存、検証はアプリケーション自体で完了する必要があります。 Redis を使用して、トークンで暗号化された情報を保存できます。ここでもう 1 つ言及しておきたいのは、一部の暗号化された情報の可変性を確保するには、内部キーの漏洩を防ぐために、最初にトークン モジュールを設計するときに複数のバージョン キーのサポートを検討するのが最善であるということです (友人がこう言ったと聞きました)彼の会社のトークン暗号化コードが従業員によって公開される前)。暗号化アルゴリズムとその具体的な実装については、ここでは詳しく説明しません。 ゲートウェイ認証に合格した後、解析されたトークン情報を、リクエストを続行する必要があるマイクロサービス層に直接渡すことができます。
アプリケーションが承認を必要とする場合 (リソースリクエストでさまざまなロールと権限を管理する必要がある)、ゲートウェイの Rest API に基づく AOP のアイデアに基づいて承認を行うことができます。認証と認可の一元管理も、Facade モードと同様に Gateway API を使用する利点の 1 つです。
負荷分散
API Gateway は、Microservice と同様、Springboot アプリケーションであり、Rest API を提供します。したがって、Docker コンテナーでも実行されます。ゲートウェイとマイクロサービス間のサービス検出では、前述のクライアント検出モードまたはサーバー検出モードを引き続き使用できます。
クラスター環境では、API Gateway は統合ポートを公開でき、そのインスタンスは異なる IP を持つサーバー上で実行されます。コンテナインフラとしてAlibaba CloudのECSを使用しているため、クラスター環境の負荷分散にはAlibaba Cloudの負荷分散SLBも使用され、ドメイン名解決にはAlibaba CloudのDNSも使用されます。次の図は、単純なネットワーク リクエストの図です:
実際には、サービス ポートとリソース アドレスを公開しないようにするために、Nginx サービスをリバース プロキシおよび外部ロードとしてサービス クラスターにデプロイすることもできます。たとえば、SLB はリクエストを Nginx サーバーに転送し、その後そのリクエストを Nginx 経由でゲートウェイ ポートに転送します。自作のコンピュータ室のクラスタの場合は、高可用性ロードバランシングセンターを構築する必要があります。クロスマシンリクエストに対処するには、Consul、Consul (Consul テンプレート) + Registor + Haproxy をサービス検出および負荷分散センターとして使用するのが最善です。
キャッシュ
一部の高 QPS リクエストの場合、API Gateway でマルチレベル キャッシュを実行できます。分散キャッシュは Redis、Memcached などを使用できます。リアルタイム要件が高くなく、変更頻度は低いが QPS が高い一部のページレベルのリクエストの場合は、ゲートウェイ層でローカル キャッシュを実行することもできます。また、ゲートウェイを使用すると、キャッシュ ソリューションをより柔軟で多用途にすることができます。
API Gatewayのエラー処理
Gatewayの具体的な実装プロセスでは、エラー処理も非常に重要です。ゲートウェイのエラー処理では、Hystrix を使用してリクエスト サーキット ブレーカーを処理できます。また、RxJava に付属する onErrorReturn コールバックも、エラー情報の戻りを簡単に処理できます。サーキット ブレーカー メカニズムでは、次の側面に対処する必要があります:
サービス リクエストのフォールトトレラントな処理
合理的なゲートウェイとして、データ フローとイベント フローの処理のみを担当する必要があり、ビジネスロジックを処理しません。複数のマイクロサービスからのリクエストを処理する場合、マイクロサービス リクエストがタイムアウトして使用できなくなる場合があります。一部の特定のシナリオでは、部分的な障害を合理的に処理する必要があります。たとえば、上記の例の「ユーザー注文リスト」では、「ユーザー」マイクロサービスでエラーが発生しても、「注文」データのリクエストには影響しません。最善の対処法は、デフォルトのアバターやデフォルトのユーザーニックネームを表示するなど、その時点で間違ったユーザー情報要求に対してデフォルトのデータを返すことです。その後、通常の注文と商品情報のリクエストに対して正しいデータが返されます。 「Order」フィールドのマイクロサービスが異常である場合など、主要なマイクロサービス リクエストが異常である場合は、クライアントにエラー コードと適切なエラー メッセージが与えられる必要があります。この種の処理は、システムの一部が使用できない場合のユーザー エクスペリエンスの向上を図ることができます。 RxJava を使用する場合、具体的な実装方法は、onErrorReturn を記述し、さまざまなクライアント リクエストに対してエラー データの互換性を持たせることです。
例外のキャプチャと記録
ゲートウェイは主にリクエストの転送とマージを担当します。問題を明確にトラブルシューティングし、特定のサービスまたはどの Docker コンテナの問題を特定するために、ゲートウェイはさまざまな種類の例外やビジネス エラーをキャプチャして記録できる必要があります。 FeignClient を使用してマイクロサービス リソースを要求する場合、ErrorDecoder インターフェイスを実装することで、応答結果をさらにフィルターし、すべての要求情報をログに記録できます。 Spring Rest Template を使用している場合は、カスタマイズされた RestTempate を定義し、返された ResponseEntity を解析できます。シリアル化された結果オブジェクトを返す前に、エラー メッセージをログに記録します。
タイムアウトメカニズム
ゲートウェイ スレッドのほとんどは IO スレッドであり、特定のマイクロサービス リクエストがブロックされるのを防ぐために、ゲートウェイには待機中のスレッドが多すぎて、スレッド プールやキューなどのシステム リソースが使い果たされます。タイムアウト インターフェイスでサービスの正常な低下を実行できるように、ゲートウェイにタイムアウト メカニズムを提供する必要があります。
SpringCloud の Feign プロジェクトに Hystrix を統合しました。 Hystrix は、タイムアウト処理のための比較的包括的なサーキット ブレーカー メカニズムを提供します。デフォルトでは、タイムアウトメカニズムは有効になっています。タイムアウト関連のパラメーターの構成に加えて、Netflix は、Hytrix に基づくリアルタイム監視 Netflix-Dashboard も提供します。クラスター サービスは、Netflix-Turbine を使用して追加展開するだけで済みます。一般的な Hytrix 構成項目については、「Hytrix 構成」を参照してください。
RxJava の Observable リアクティブ プログラミングを使用していて、さまざまなリクエストにさまざまなタイムアウトを設定したい場合は、Observable の timeout() メソッドのパラメータでコールバック メソッドとタイムアウト時間を直接設定できます。
再試行メカニズム
一部の主要なビジネスでは、リクエストがタイムアウトしたときに正しいデータを確実に返すために、ゲートウェイは再試行メカニズムを提供する必要があります。 SpringCloudFeign を使用する場合、その組み込みリボンはデフォルトの再試行構成を提供します。これは spring.cloud.loadbalancer.retry.enabled=false を設定することでオフにできます。リボンが提供する再試行メカニズムは、リクエストがタイムアウトしたとき、またはソケット読み取りタイムアウトが発生したときにトリガーされます。再試行の設定に加えて、再試行時間のしきい値と再試行回数をカスタマイズすることもできます。
Feign に加えて Spring RestTemplate を使用するアプリケーションの場合、リクエストを再試行する必要がある場合 (固定形式のエラー コード メソッドなど)、カスタマイズされた RestTemplate を使用して、返された ResponseEntity オブジェクトの結果を解析できます。 retry) 戦略)、リクエストのインターセプトはインターセプターを通じて実行され、複数のリクエストはコールバックを通じて呼び出されます。
マイクロサービス アーキテクチャでは、独立した API ゲートウェイを通じて、統合されたリクエストの転送、マージ、プロトコル変換を実行できます。さまざまなクライアントのリクエストデータにより柔軟に適応できます。さらに、さまざまなクライアント (たとえば、H5 と iOS では表示データが異なります) やさまざまなバージョンと互換性のあるリクエストをゲートウェイで適切にシールドして、マイクロサービスをより純粋にすることができます。マイクロサービスは、内部ドメイン サービスとイベント処理の設計にのみ重点を置く必要があります。
API ゲートウェイは、マイクロサービス リクエストに対して特定のフォールト トレランスとサービス低下を実行することもできます。リアクティブ プログラミングを使用して API ゲートウェイを実装すると、スレッドの同期と同時実行コードがよりシンプルで保守しやすくなります。マイクロサービスのリクエストは、FeignClint を通じて統合できます。コードも非常に階層的になります。以下の図は、要求されたクラス階層の例です。
Clint は、サービス検出 (Eureka を使用した自己登録用) の統合、負荷分散、リクエストの作成、および ResponseEntity オブジェクトの取得を担当します。
Translator は、DDD の耐腐食層の概念と同様に、ResponseEntity を Observable
Adapter は各 Translator を呼び出し、Observable 関数を使用して要求されたデータ ストリームをマージします。複数のデータ アセンブリがある場合は、アセンブラーのレイヤーを追加して、DTO オブジェクトからモデルへの変換を特別に処理できます。
Controller は、Restful リソースの管理を提供します。各コントローラーは、固有のアダプター メソッドのみを要求します。
前回の記事では主にマイクロサービスのサービスディスカバリ、サービス通信、APIゲートウェイについて紹介しました。全体的なマイクロサービス アーキテクチャのモデルが最初に表示されます。実際の開発、テスト、運用環境。 Docker を使用してマイクロサービスを実装する場合、クラスターのネットワーク環境はより複雑になります。マイクロサービス アーキテクチャ自体は、複数のコンテナ サービスを管理する必要があり、各マイクロサービスを個別にデプロイ、拡張、監視する必要があることを意味します。引き続き、Docker マイクロサービスの継続的インテグレーション デプロイメント (CI/CD) を実行する方法を紹介します。
イメージ ウェアハウス
Docker を使用してマイクロサービスをデプロイするには、マイクロサービスを Web サーバーにデプロイして war ファイルにパッケージ化するのと同じように、マイクロサービスを Docker イメージにパッケージ化する必要があります。 Docker イメージが Docker コンテナ内で実行されるだけです。
Springboot サービスの場合、Apache Tomcat サーバーを含む Springboot と、Java ランタイム ライブラリを含むコンパイル済み Java アプリケーションが Docker イメージに直接パッケージ化されます。
パッケージ化と配信(プル/プッシュ)イメージを一元管理するため。通常、企業は独自のプライベート ミラー データベースを確立する必要があります。実装も非常に簡単です。 Docker ハブのミラー ウェアハウスの Registry2 のコンテナ バージョンは、サーバーに直接デプロイできます。現在の最新バージョンは V2 です。
コード ウェアハウス
コードの送信、ロールバック、その他の管理も、プロジェクトの継続的統合の一部です。一般に、会社のコード ウェアハウス用のプライベート リポジトリを確立することも必要です。 SVN や GIT などのコード バージョン管理ツールを使用できます。
現在、同社ではGitlabを利用しており、GitのDockerイメージによるインストールやデプロイの操作も非常に便利です。具体的な手順については、docker gitlab install を参照してください。迅速にビルドしてパッケージ化するために、Git とレジストリを同じサーバーにデプロイすることもできます。
プロジェクトの構築
Springboot プロジェクトでは、ビルド ツールは Maven または Gradle です。 Gradle は Maven よりも柔軟であり、Springboot アプリケーション自体が構成解除可能であるため、DSL 自体も XML よりも簡潔で効率的な Gradle を使用するのが適しています。
Gradle はカスタム タスクをサポートしているためです。したがって、マイクロサービスの Dockerfile を作成した後、Gradle のタスク スクリプトを使用してそれを構築し、Docker イメージにパッケージ化できます。
Transmode-Gradlew プラグインなど、Docker イメージを構築するためのオープンソース Gradle ツールもいくつかあります。サブプロジェクト (単一のマイクロサービス) 用の Docker イメージの構築に加えて、リモートのイメージ ウェアハウスへのイメージのアップロードも同時にサポートできます。運用環境のビルド マシンでは、プロジェクトのビルド、Docker イメージのパッケージ化、およびイメージのプッシュを 1 つのコマンドで直接実行できます。
コンテナ オーケストレーション テクノロジ
Docker イメージが構築された後、各コンテナは異なるマイクロサービス インスタンスを実行するため、サービスもコンテナ間で分離してデプロイされます。オーケストレーション テクノロジを通じて、DevOps はコンテナのデプロイと監視を軽量に管理し、コンテナ管理の効率を向上させることができます。
現時点では、Ansible、Chef、Puppet などの一部の一般的なオーケストレーション ツールもコンテナーをオーケストレーションできます。ただし、それらはいずれもコンテナー専用のオーケストレーション ツールではないため、使用する場合は自分でいくつかのスクリプトを作成し、Docker コマンドと組み合わせる必要があります。たとえば、Ansible は実際に、クラスター コンテナーの非常に便利なデプロイと管理を実現できます。 Ansible は現在、そのチームが開発したコンテナ テクノロジーの統合ソリューション、Ansible Container を提供しています。
クラスター管理システムはホストをリソース プールとして使用し、各コンテナーのリソース要件に基づいてコンテナーをスケジュールするホストを決定します。
現在、Docker コンテナのスケジューリングとオーケストレーションを取り巻く比較的成熟したテクノロジーには、Google の Kubernetes (以下、k8s と略します)、Docker クラスターを管理するためのマラソンと組み合わせた Mesos、および Docker バージョン 1.12.0 で正式に提供される Docker Swarm があります。その上。オーケストレーション テクノロジは、コンテナ テクノロジの焦点の 1 つです。チームに合ったコンテナ オーケストレーション テクノロジを選択すると、運用とメンテナンスをより効率的に自動化することもできます。
Docker Compose
Docker Compose は、YAML ファイルを通じて実行する必要があるアプリケーションを構成し、compose up コマンドを通じて複数のサービスに対応するコンテナ インスタンスを起動します。 Compose は Docker に統合されていないため、個別にインストールする必要があります。 Compose はマイクロサービス プロジェクトの継続的統合に使用できますが、大規模なクラスターのコンテナー管理には適していません。大規模なクラスターでは、Compose を Ansible と組み合わせてクラスターのリソース管理とサービス ガバナンスを行うことができます。
クラスター内にサーバーがあまりない状況では、Compose を使用できます。主な手順は次のとおりです:
Docker Swarm 2016 年に Docker の 1.12 バージョンがリリースされた後、新しいバージョンの Docker には Docker swarm モードが搭載されました。追加のプラグイン ツールをインストールする必要はありません。 Docker チームも昨年からサービス オーケストレーション テクノロジに注目し始めており、組み込みの Swarm モードを通じてサービス オーケストレーション市場の一部を獲得したいと考えていることがわかります。
チームが新しいバージョンの Docker の使用を開始する場合は、クラスター化されたコンテナーのスケジューリングと管理に Docker swarm モードを選択できます。 Swarm は、ローリング アップデート、ノード間のトランスポート層セキュリティ暗号化、負荷分散などもサポートしています。
DockerSwarm の使用例については、以前に書いた記事「docker-swarm を使用して継続的統合クラスター サービスを構築する」を参照してください。
KubernetesKubernetes は、Go 言語を使用して実装された Google のオープンソース コンテナ クラスター管理システムであり、アプリケーションのデプロイ、メンテナンス、拡張メカニズムなどの機能を提供します。現在、k8s は GCE、vShpere、CoreOS、OpenShift、Azure およびその他のプラットフォームで使用できます。現在、中国の Aliyun も k8s をベースとしたサービス管理プラットフォームを提供しています。物理マシンまたは仮想マシンに基づいて構築された Docker クラスターの場合は、k8s を直接デプロイして実行することもできます。マイクロサービス クラスター環境では、Kubernetes はマシン間でマイクロサービス コンテナー インスタンスを簡単に管理できます。
ポッドは、Kubernetes の最小の管理要素であり、ポッド内で実行される 1 つ以上のコンテナーです。ポッドのライフサイクルは非常に短く、スケジューリングが失敗したり、ノードがクラッシュしたり、他のリソースがリサイクルされたりすると、終了します。
ラベルは、ポッドに関連付けることができるキー/値のストレージ構造であり、主にポッドとグループサービスをマークするために使用されます。マイクロサービスは、ラベル セレクター (セレクター) を使用してポッドを識別します。
レプリケーション コントローラーは、k8sMaster ノードのコア コンポーネントです。指定された数のポッド レプリカ (レプリカ) が Kubernetes クラスター内で常に実行されていることを確認するために使用されます。つまり、自己修復メカニズムの機能を提供し、縮小と拡張、およびローリング アップグレードにも役立ちます。
サービスは、ポッドのグループの戦略を抽象化したものです。これは、k8s 管理の基本要素の 1 つでもあります。サービスはラベルを通じてポッドのグループを識別します。作成時に、ローカル クラスターの DNS も作成されます (サービスに対応するポッドのサービス アドレスを保存するため)。したがって、クライアントは DNS を要求して、現在利用可能な一連の Pod の IP アドレスを取得するように要求します。その後、リクエストは各ノードで実行されている kube-proxy を介してポッドの 1 つに転送されます。負荷分散のこの層は透過的ですが、現在の k8s 負荷分散戦略はあまり完全ではなく、デフォルトはランダムです。
マイクロサービス アーキテクチャ システムでは、適切な継続的インテグレーション ツールにより、チームの運用と開発の効率が大幅に向上します。現在、Jenkins と同様に、Docker 用の継続的統合プラグインがありますが、まだ多くの不完全な点があります。したがって、特に Docker コンテナ オーケストレーション テクノロジを扱う Swarm、k8s、および Mesos を選択することをお勧めします。または、CI 用の Jenkins + CD 用の k8s など、複数のテクノロジーを組み合わせます。
Swarm、k8s、Mesos にはそれぞれ独自の機能があり、コンテナの継続的なデプロイ、管理、監視をサポートします。 Mesos はデータセンター管理もサポートします。 Docker swarm モードは、既存の Docker API を拡張し、Docker リモート API の呼び出しと拡張を通じて、コンテナーを指定したノードで実行するようにスケジュールできます。 Kubernetes は現在市場で最大のオーケストレーション テクノロジであり、多くの大企業も k8s ファミリに参加しています。K8s はクラスタ アプリケーションの拡張、保守、管理においてより柔軟ですが、負荷分散戦略は比較的大雑把です。 Mesos は一般的なスケジューリングに重点を置き、さまざまなスケジューラを提供します。
サービス オーケストレーションの場合は、チームに最適なものを選択する必要がありますが、初期マシンの数が少なく、クラスター環境が複雑でない場合は、継続的統合のために Ansible+Docker Compose に加えて Gitlab CI を使用することもできます。 。
サービス クラスター ソリューション
企業が最初からマイクロサービス アーキテクチャをレイアウトする場合でも、従来の単一アプリケーション アーキテクチャからマイクロサービスに移行する場合でも、Docker を使用してマイクロサービス アプリケーションをデプロイおよび実行する練習をする場合。すべてが、複雑なクラスターにおけるサービスのスケジューリング、オーケストレーション、監視、その他の問題を処理できる必要があります。以下では主に、分散サービス クラスターで Docker をより安全かつ効率的に使用する方法と、アーキテクチャ設計で考慮する必要があるすべての側面を紹介します。
負荷分散
ここで話しているのは、純粋なサーバー API の場合は、ゲートウェイ API の負荷分散を指します。Nginx が使用されている場合は、負荷分散を指します。 Nginxの。現在、Alibaba Cloud の負荷分散サービス SLB を使用しています。主な理由の 1 つは、DNS ドメイン ネーム サービスにバインドできることです。事業を始めたばかりの企業では、Webインターフェースから負荷分散の重みを設定できるため、部分リリースやテスト・検証、ヘルスチェック監視などに便利です。効率性と運用コストとメンテナンスコストの節約の観点から、これはより適切な選択です。
Nginx や Haproxy を使用するなど、7 層の負荷分散を自分で構築する場合は、負荷分散を担当するクラスターも高可用性であり、便利なクラスター監視、Blue-Green デプロイメント、およびその他の機能を提供することを確認する必要があります。 。
リレーショナル データベース (RDBMS)
マイクロサービスの場合、使用されるストレージ テクノロジは主に企業のニーズに基づいています。コストを節約するために、通常は Mysql が使用されます。Mysql エンジンを選択する場合は、InnoDB エンジンを選択することをお勧めします (バージョン 5.5 より前のデフォルトは MyISAM でした)。 InnoDB は同時実行性を処理する場合により効率的であり、そのクエリ パフォーマンスのギャップは、キャッシュ、検索、その他のソリューションによって補うこともできます。データのコピーとバックアップを処理するための InnoDB の無料ソリューションには、binlog と mysqldump が含まれます。ただし、自動化されたバックアップとリカバリ、および監視可能なデータセンターを実現するには、DBA または運用保守チームが依然として必要です。相対的なコストも高くなります。新興企業の場合は、国内外の比較的大規模なクラウド コンピューティング プラットフォームが提供する PaaS サービスに依存することも検討できます。
マイクロサービスは通常、ビジネス領域に応じて分割されるため、最初からマイクロサービス用のサブライブラリを設計することが最善です。テーブルの細分化が必要かどうかは、各マイクロサービスの特定のビジネス分野の展開とデータのサイズに基づいて詳細な分析が必要です。ただし、「注文」などの比較的コアなフィールドのモデルについては、サブテーブルフィールドを事前に設計し、予約しておくことが推奨されます。
KV モデル データベース (Key-Value-store)
Redis は、オープンソースの Key-Value 構造データベースです。メモリに基づいており、効率的なキャッシュ パフォーマンスがあり、永続性もサポートしています。 Redis には主に 2 つの永続化メソッドがあります。 1 つは RDB です。RDB は、指定された時間間隔でデータ セットのポイントインタイム スナップショットを生成し、それをメモリからディスクに書き込み、永続化します。 RDB方式はある程度のデータ損失は発生しますが、パフォーマンスは良好です。もう 1 つは AOF で、その書き込みメカニズムは InnoDB の binlog に似ており、すべて Redis プロトコル形式で保存されます。これら 2 種類の永続性は同時に存在できます。Redis が再起動されると、最初に AOF ファイルがデータの復元に使用されます。永続化はオプションであるため、Redis の永続化を無効にすることもできます。
実際のシナリオでは、永続性を保持することをお勧めします。たとえば、Redis を使用すると、現在普及している SMS 検証コードの検証を解決できます。マイクロサービス アーキテクチャ システムでは、Redis を使用して一部の KV データ構造シナリオを処理することもできます。軽量データ ストレージ ソリューションは、軽量ソリューションを重視するマイクロサービスのアイデアにも非常に適しています。
実際には、Redis をキャッシュして永続化し、2 つの機能を別々のライブラリに分割します。
統合 Springboot プロジェクトでは、spring-boot-starter-data-redis を使用して、Redis データベース接続と基本構成に加え、spring-data-redis によって提供される豊富なデータ APIOperations を実行します。
さらに、高スループットを必要とするアプリケーションの場合は、Memcached を使用して単純な KV データ構造をキャッシュすることを検討できます。大量のデータを読み取るのに適していますが、サポートされているデータ構造タイプは比較的単純です。
グラフ データベース (グラフ データベース)
ソーシャル関連のモデル データのストレージが含まれます。グラフ データベースは、交差するリレーショナル データベースにとってより効率的で柔軟な選択肢です。グラフデータベースも Nosql の一種です。 KV とは異なり、保存されるデータは主にデータ ノード (node)、方向関係 (Relationship)、およびノードとリレーションシップ上のプロパティ (Property) です。
マイクロサービスの主な開発言語として Java を使用する場合は、Neo4j を選択するのが最善です。 Neo4j は、ACID をサポートする Java ベースのグラフ データベースです。豊富な JavaAPI を提供します。パフォーマンスの点では、グラフ データベースのローカルな性質により、トラバース、特に大規模なディープ トラバースが非常に高速になります。これは、リレーショナル データベースの複数テーブルの関連付けでは実現できません。
下の写真は、Neo4j の WebUI ツールを使用して表示された公式の入門データ モデルの例です。この例のステートメント MATCH p=()-[r:DIRECTED]->() RETURN p LIMIT 25 は、Neo4j - Cypher によって提供されるクエリ言語です。
SpringData のプロジェクト Spring Data Neo4j をプロジェクトで使用するときに統合できます。そしてSpringBootStartersspring-boot-starter-data-neo4j
ドキュメントデータベース
現在広く使われているオープンソースのドキュメント指向データベースはMongodbを利用することができます。 Mongo は、特に Json データ構造ストレージに関して、高可用性、高スケーラビリティ、および柔軟なデータ構造ストレージを備えています。ブログやコメントなどのモデルの保存に適しています。
検索テクノロジー
開発プロセスでは、長くて複雑で保守が難しい複数テーブルのクエリ SQL や、複数のテーブルに関連するさまざまなサブクエリ ステートメントを作成している人をよく見かけます。特定のドメイン モデルでそのようなシナリオが多数ある場合は、検索ソリューションの追加を検討する時期が来ています。すべてを解決するために、特にクエリ シナリオを解決するために SQL を使用しないでください。 DB 監視システムが設置されていない場合、クエリ ステートメントが遅いという問題により DB が停止する場合もあります。この問題のトラブルシューティングは困難になる可能性があります。
Elasticsearch は、Apache Lucene に基づくオープンソースのリアルタイム分散検索および分析エンジンです。 Springboot プロジェクトは、統合メソッド spring-boot-starter-data-elasticsearch および spring-data-elasticsearch も提供します。
検索クラスターを構築するには、Docker を使用できます。具体的な構築方法については、「Docker を使用した Elasticsearch クラスターの構築」を参照してください。Springboot プロジェクトの統合については、「Springboot Microservices での検索サービスの統合」を参照してください。これまでのところ、Spring Data Elasticsearch の最新バージョンは ES のバージョン 5.x をサポートしており、バージョン 2.x の多くの問題点を解決できます。
小規模な検索クラスターの場合は、低構成のマシンを 3 台使用し、ES Docker を使用して構築できます。 PaaS サービスの一部の商用バージョンを使用することもできます。どのように選択するかは、チームやビジネスの規模やシナリオによって異なります
。
現在、ES に加えて、より広く使用されているオープンソース検索エンジンは Solr で、これも Lucene をベースにしており、テキスト検索に重点を置いています。 ES のテキスト検索は、Solr ほど優れていません。ES は主に分散サポートのサポートに重点を置いており、Solr と比較して、クラスターのステータスを維持するためのサービス検出コンポーネント Zen が組み込まれています (これを実現するには、Zookeeper などの助けが必要です)。ディストリビューション)、展開もより軽量になります。 ES はクエリの分析に加えて、ログの収集、分析、処理を統合することもできます。
メッセージ キュー
前の記事で説明したように、メッセージ キューはマイクロサービスの優れたデカップリング通信方法として使用できます。分散クラスターのシナリオでは、分散条件下での最終的な一貫性に対する技術的な基本保証も提供できます。また、メッセージ キューを使用してトラフィックの削減を処理することもできます。
メッセージキューの比較はここでは繰り返しません。同社は現在、Alibaba Cloud の ONS を使用しています。メッセージ キューの使用には依然として高可用性と容易な管理と監視が必要であるため、安全で信頼性の高いメッセージ キュー プラットフォームを選択しました。
セキュリティテクノロジー
セキュリティは、アーキテクチャを行う際に考慮する必要がある基礎です。インターネット環境は複雑であり、サービスのセキュリティを保護することは、ユーザーに対する基本的な義務でもあります。セキュリティ テクノロジは幅広いトピックをカバーしています。この記事では、いくつかの一般的な問題と一般的に使用される方法を選択して簡単に紹介します。
サービス インスタンスのセキュリティ
分散クラスター自体がサービス インスタンスのセキュリティを保証します。サーバーまたは特定のサービス インスタンスに問題が発生した場合、負荷分散によりリクエストが他の利用可能なサービス インスタンスに転送されます。しかし、多くの企業は独自のコンピューター室を構築しており、このレイアウトは実際にはさらに危険です。サーバーのバックアップと災害復旧を完全に保証できないためです。最も恐ろしいのは、データベースも同じコンピュータ室にあり、メインサーバーとバックアップサーバーが一緒にあることです。セキュリティが保証されないだけでなく、日々の運用と保守のコストも比較的高くなります。ファイアウォール セキュリティ ポリシーの構成にも注意を払う必要があります。
可能であれば、可用性が高く、スケーラビリティが高く、安定した IaaS プラットフォームを使用するようにしてください。
1. ネットワーク攻撃の防止
現在、いくつかの主要なネットワーク攻撃があります。
SQL インジェクション: 永続層フレームワークに応じて、対応戦略が異なります。 JPAを使用する場合は、JPAの仕様に従っていれば、基本的には心配する必要はありません。
XSS 攻撃: パラメーターのエスケープと検証を適切に実行します。詳細については、XSS 防御
CSRF 攻撃: トークンと Http ヘッダー情報の Refer 検証を適切に行うを参照してください。詳細については、「CSRF 防御
DDOS 攻撃」を参照してください。大規模トラフィックの DDoS 攻撃では、通常、防御性の高い IP が使用されます。一部のクラウド コンピューティング プラットフォームの高防御 IP にアクセスすることもできます。
上記では、一般的な攻撃をいくつか列挙しただけです。さらに詳しく知りたい場合は、REST セキュリティ防止テーブルを参照してください。ネットワーク セキュリティの分野では、一般にスタートアップ企業に無視されがちです。運用および保守のセキュリティ チームが存在しない場合は、Alibaba Cloud-Cloud Shield のような製品を使用するのが最善です。心配もコストも節約できます。
2. セキュリティプロトコルを使用する
これは、Restful APIを使用したマイクロサービス通信であっても、CDNを使用した場合でも、DNSサービスを使用した場合でも、言うまでもありません。 HTTP プロトコルに関しては、一律に HTTPS を使用することをお勧めします。アプリケーションのサイズに関係なく、トラフィック ハイジャックを防ぐ必要があります。そうしないと、ユーザーに非常に悪いエクスペリエンスをもたらすことになります。
3. 認証
API Gateway は以前にもマイクロサービスの認証を導入しました。マイクロサービス自体に加えて、Mysql、Redis、Elasticsearch、Eureka など、使用する一部のサービスでも認証を設定し、イントラネット経由でアクセスを試行する必要があります。あまりにも多くのポートを外部に公開しないでください。マイクロサービスの API ゲートウェイの場合、認証に加えて、フロントエンドが Nginx リバース プロキシ経由で API レイヤーをリクエストすることが最適です。
コンテナテクノロジーに基づくマイクロサービスの監視システムは、より複雑なネットワークとサービス環境に直面しています。ログの収集と監視によってマイクロサービスの侵入を軽減し、開発者にとってより透過的なものにする方法は、多くのマイクロサービス DevOps が常に考え、実践していることです。
1. マイクロサービスのログの収集
マイクロサービスの API レイヤーのモニタリングには、API ゲートウェイから各マイクロサービスへの呼び出しパスの追跡、収集、分析が必要です。 Rest API を使用する場合は、すべてのリクエストを収集するために、Spring Web の OncePerRequestFilter を使用してすべてのリクエストをインターセプトできます。ログを収集するときに、リクエストの rt を記録することも最適です。
アクセス、リクエスト、その他の情報を記録することに加えて、API 呼び出しのリクエスト追跡を実行する必要もあります。各サービスとゲートウェイのログを記録するだけでは、ゲートウェイ ログで例外が発生したときに、マイクロサービスのどのコンテナー インスタンスに問題があるのかわかりません。コンテナ数が一定レベルに達すると、すべてのコンテナおよびサービスインスタンスのログを確認することができなくなります。比較的単純な解決策は、コンテナ情報を含む一意に識別可能なトレース文字列をすべてのログ情報に追加することです。
ログを収集した後も、分析する必要があります。 E.L.Kの技術システムを利用すれば、Elasticsearchのリアルタイム分散機能を柔軟に利用することができます。 Logstash はログを収集して分析し、データを Elasticsearch に同期できます。 Kibana は Logstash と ElasticSearch を組み合わせて、ログ分析を容易にし、ログ データの視覚的な管理を強化する優れた WebUI を提供します。
データ量の多いログを収集する場合、収集パフォーマンスを向上させるために、上記のメッセージキューを使用する必要があります。最適化されたアーキテクチャは以下の通りです:
2. 基本サービスの呼び出しログ収集
マイクロサービスのすべてのRest APIのログ収集と分析を通じてリクエスト情報を監視できます。
サービス内では、ミドルウェアおよびインフラストラクチャ呼び出し (Redis、Mysql、Elasticsearch などを含む) のパフォーマンスのログ収集と分析も必要です。
ミドルウェアサービスのログ収集については、現在、サービスによって呼び出されるキャッシュとリポジトリ(検索とDBを含む)と呼ばれる基本的なメソッドの動的プロキシメソッドを介してロギングメソッドをインターセプトしてコールバックできます。具体的な実装方法は、バイトコード生成フレームワーク ASM を使用できます。メソッドのロジック インジェクションについては、以前に書いた記事「ASM を使用してメソッド ロジックを動的にインジェクトする」を参照してください。メンテナンスは簡単ではありませんが、比較的 API フレンドリーな Cglib を使用することもできます。
アーキテクチャの 5 つの要素:
最後に、アーキテクチャの 5 つのコア要素に基づいて、Docker マイクロサービス アーキテクチャを構築するために使用する技術システムを確認しましょう:
高性能
メッセージ キュー、RxJava 非同期同時実行性、分散キャッシュ、ローカル キャッシュ、HTTP Etag キャッシュ、Elasticsearch を使用したクエリの最適化、CDN など。
可用性コンテナサービスクラスター、RxJavaサーキットブレーカー処理、サービス低下、メッセージべき等処理、タイムアウトメカニズム、リトライメカニズム、分散結果整合性など。
スケーラビリティ: サーバー クラスターのスケーラビリティ、コンテナ オーケストレーション Kubernetes、データベース シャーディングとテーブル シャーディング、Nosql の線形スケーラビリティ、検索クラスターのスケーラビリティなど。
スケーラビリティ Docker ベースのマイクロサービス自体は、スケーラビリティのために生まれています。
セキュリティ
JPA/Hibernate、SpringSecurity、高防御IP、ログ監視、HTTPS、Nginxリバースプロキシ、HTTP/2.0など
サービス クラスター ソリューションの場合、実際、マイクロサービス アーキテクチャであっても SOA アーキテクチャであっても、比較的一般的です。一部のミドルウェアクラスタの構築のみDockerを利用できます。 Docker ps の一文だけで実行中のサービス情報を簡単に問い合わせることができ、基本的なサービスのアップグレードにも便利です。
優れたクラスター アーキテクチャ設計の追求に終わりはありません。スタートアップ企業の多くの技術的な友人に連絡すると、誰もがサービスを迅速に構築、開発、リリースすることを好みます。しかし一方で、マイクロサービスのアーキテクチャはより複雑になり、時間の無駄になるのではないかという懸念もあります。しかし、マイクロサービス自体はアジャイル モードの優れた実践方法です。これらの友人は、ビジネスが急速に発展すると、サービスの分割、データベースのサブデータベースとテーブル、およびメッセージを介したヌードルのような同期コードの分離という問題に直面することがよくあります。パフォーマンスを最適化したいと考えていますが、開始する方法がありません。
この記事では主にDockerのマイクロサービス実践のための技術ソリューションを厳選して紹介します。さまざまなビジネスやチームが、さまざまなアーキテクチャ システムや技術ソリューションに適している場合があります。
建築家として、会社の短期および長期の戦略計画に基づいて長期的なレイアウトを作成する必要があります。少なくとも、基本アーキテクチャは 3 年間の開発をサポートできる必要があり、その間、新しいテクノロジーを継続的に導入し、サービスのアップグレードと継続的なコード層の再構築を実行できます。おそらく、アーキテクトが完全なシステムをゼロから構築するのにそれほど時間はかかりません。最も重要なことは、チーム内でドメイン駆動設計を継続的に実装することです。そして、チームがクリーン コードに従い、アジャイル開発 OvO を実施できるようにします。
Microsoft マイクロサービス アーキテクチャ eShopOnContainers の分析
関連ビデオ:Geek Academy Docker ビデオ チュートリアル - 無料のオンライン ビデオ チュートリアル
以上がDocker のコンテナ技術を使用してサービス アーキテクチャ システム DevOps - JAVA アーキテクチャをレイアウトするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。