このような問題を防ぐために、分散アーキテクチャ、つまり、すべてのコンポーネントを水平に拡張できるアーキテクチャがよく使用されます。 しかし、残念ながら、SOAを実装すると、新しい問題が発生します。つまり、サービス構成の接続性と複雑さです。
この記事では、Consulと呼ばれる発見サービスの1つについて説明します。Consulを使用すると、上記の問題を解決し、アーキテクチャをより透明で理解しやすくすることができます。
分散アーキテクチャ(SOA)とその構築の問題
疎結合コンポーネントのセットとしてアプリケーションを設計すると、最初に任意のコンポーネントをスケーリングする機能が得られます。
SOA( サービス指向アーキテクチャ )は、標準プロトコル(RESTなど)を使用して相互に通信する、弱い接続性を持つスタンドアロンコンポーネントの形でアプリケーションアーキテクチャを記述するアーキテクチャパターンです。 SOAの論理的継続(またはサブセット)はマイクロサービスアーキテクチャです。 これは、特定のサービスの機能を増やす代わりにサービスの数を増やすことに基づいており(アーキテクチャにおける単一責任の原則を反映)、継続的なプロセスとの深い統合に基づいています。
マイクロサービスアーキテクチャの実装に携わっている場合、間違いなく、サービスの相互作用の責任はアプリケーションのインフラストラクチャソリューションにあります。 単一責任の原則に準拠するサービスは、要求を受け入れて応答を返すことしかできません。 同時に、システムノード間のトラフィックのバランスをとる必要があります。弱いとはいえ、相互に依存するサービスを接続する必要があります。 そしてもちろん、システムの構成変更に対応する必要があります。
- サービスは常に追加されています。
- 一部のサービスは、ヘルスチェックに応答しなくなりました。
- 新しいコンポーネントがシステムに表示され、それらに関する情報を可能な限り効率的に広める必要があります。
- 個々のコンポーネントのバージョンが更新されます-下位互換性が失われます。
どのシステムでも、これは継続的で複雑なプロセスですが、ディスカバリサービスの助けを借りてそれを制御し、より透明にすることができます。
発見とは?
ディスカバリーは、アーキテクチャーのコンポーネント間の通信を提供するためのツール(またはツールのセット)です。 ディスカバリーを使用して、アプリケーションコンポーネント間の接続を提供しますが、 接続は提供しません。 ディスカバリーは、コンポーネントに関するすべてのデータを保管する分散アーキテクチャーに関するメタ情報の一種のレジスターと考えることができます。 これにより、最小限の手動介入でコンポーネントの相互作用が可能になります(つまり、ZeroConfの原則に従って)。
分散アーキテクチャの構築における発見の役割
ディスカバリーサービスは、分散アーキテクチャー内で接続が基づく3つの主要な機能を提供します。
- クラスター内のサービスに関するメタ情報の一貫性。
- コンポーネントの可用性を記録および監視するメカニズム。
- コンポーネントを検出するメカニズム。
各アイテムの値を詳細に明らかにします。
一貫性
分散アーキテクチャは、コンポーネントを水平方向に拡張できることを意味しますが、クラスターの状態に関する最新情報が必要です。 ディスカバリサービスは、任意のノードに(デ)集中ストレージとそのアクセスを提供します。 コンポーネントはデータを保存でき、情報は関心のあるすべてのクラスターメンバーに配信されます。
登録と監視
新たに追加されたサービスは自身について通知する必要があり、すでに開始されているサービスは可用性を常に確認する必要があります。 これは、自動クラスター構成の前提条件です。 リソースを効率的に使用するには、トラフィックバランサーと依存ノードに現在のクラスター構成に関する情報が必要です。
発見
ディスカバリーとは、たとえばサービスが実行する役割など、サービスの検索エンジンを意味します。 特定の役割のすべてのサービスの場所をリクエストできます。正確な番号と特定のアドレスは知らず、ディスカバリサービスのアドレスのみを知っています。
発見の実装としてのConsul.io
この記事では、Consulベースのディスカバリー実装について説明します。
Consulは、HashiCorp(Vagrant、TerraForm、Otto、Atlasなどの製品を開発)の分散型フォールトトレラントディスカバリサービスです。
Consulは分散サービスです。つまり、Consulエージェントは各ホストにインストールされ、クラスターの完全なメンバーです。 したがって、サービスはネットワーク内のディスカバリアドレスを知る必要はなく、ディスカバリへのすべてのリクエストはローカルアドレス127.0.0.1に対して行われます。
Consulについて他に知っておくべきこと:
情報の普及には、 結果整合性モデルに基づいたアルゴリズムを使用します。
エージェントはゴシッププロトコルを使用して情報を広めます。
サーバーは、Raftアルゴリズムを使用してリーダーを選択します。
リーダーは、情報変更のすべての要求を受け入れるサーバーです。 データベースから類推すると、これはマスター/スレーブ複製のコンテキストでのマスターです。 他のすべてのサーバーは、リーダーからのデータを複製します。 DBレプリケーションとの主な違いは、リーダーに障害が発生した場合、他のすべてのサーバーが新しいリーダーの選出メカニズムを開始し、選出後に自動的に複製を開始することです。 切り替えメカニズムは完全に自動化されており、管理者の介入は不要です。
各インスタンスは、エージェントとサーバーの2つのモードで動作できます。 違いは、エージェントが情報の配布ポイントであり、サーバーが登録ポイントであることです。 つまり エージェントは読み取り専用要求を受け入れ、サーバーは既存の情報に変更を加えることができます(サービスの登録と削除)。 実際、いずれの場合でも、ローカルアドレスにリクエストを実行しますが、唯一の違いは、読み取りリクエストがローカルホスト上のエージェントによって処理され、データ変更のリクエストがリーダーにリダイレクトされることです。リーダーはクラスター全体にデータを保存および配信します。 ローカルエージェントが現時点でリーダーでない場合、変更要求はローカルで完全に処理され、クラスター全体に分散されます。
クラスターでのConsulの使用
領事クラスターは、検出で登録されたサービスを実行する接続ノードのネットワークです。 Consulは、クラスター情報がすべてのクラスターメンバーに配信され、リクエストに応じて利用できることを保証します。 また、ピアツーピアだけでなく、Consulの用語ではデータセンターと呼ばれる、マルチピアのゾーン分離クラスターもサポートします。 Consulを使用すると、特定のデータセンターで作業したり、他のデータセンターでアクションを実行したりできます。 データセンターは、ディスカバリーの一部として互いに分離されていません。 1つのDCのエージェントは、別のDCから情報を受け取ることができます。これは、分散システムの効果的なソリューションの構築に役立ちます。
サーバーモードで実行されているConsulエージェントは、プライマリロールに加えて、潜在的なクラスターリーダーのロールも受け取ります。 クラスターで少なくとも3つのサーバーモードエージェントを使用して、フォールトトレランスを提供することをお勧めします。 サーバーモードを使用しても、エージェントのコア機能に制限はありません。
新しいノードをクラスターに入力するとき、クラスター内のノードのアドレスを知る必要があります。 コマンドを実行することにより:
consul join node_ip_address
クラスターに新しいノードを登録すると、しばらくすると、このノードでクラスター全体の状態に関する情報が利用できるようになります。 したがって、新しいノードは他のノードからの要求に使用できます。
ノードのタイプ:内部、外部
Consulでは、2つの方法でサービスを登録できます。
- サービスがConsulと独立して通信できる場合のみ、HTTP APIまたはエージェント構成ファイルを使用します。
- サービスがConsulと通信できない場合に備えて、サービスをサードパーティコンポーネントとして登録します。
両方のケースをより詳細に検討します。
Consulが提供するHTTP APIを使用して、コンポーネントを正しく登録し、ディスカバリーでサービスを削除することができます。 これら2つの状態に加えて、
maintenance
状態を使用できます。 このモードでは、サービスは使用不可としてマークされ、DNSおよびAPI要求に表示されなくなります。
コンポーネント登録リクエストの例を考えてみてください(JSONはPUTリクエストで渡す必要があります):
http://localhost:8500/v1/agent/service/register { "ID": "redis1", "Name": "redis", "Tags": [ "master", "v1" ], "Address": "127.0.0.1", "Port": 8000, "Check": { "Script": "/usr/local/bin/check_redis.py", "HTTP": "http://localhost:5000/health", "Interval": "10s", "TTL": "15s" } }
ディレクトリからコンポーネントを削除するリクエストの例:
http://localhost:8500/v1/agent/service/deregister/[ServiceID]
サービスをメンテナンスモードに移行するリクエストの例:
http://localhost:8500/v1/agent/service/maintenanse/[ServiceID]?enable=true|false
イネーブルフラグを使用して、状態を切り替え、オプションのreasonパラメータを追加できます。このパラメータには、コンポーネントがメンテナンスモードに切り替わる理由のテキスト説明が含まれます。
外部サービスを登録する必要があり、Consulに登録するために「教える」機会がない場合は、サービスプロバイダーとしてではなく、外部サービスとして登録できます。 登録後、DNSを介して外部サービスに関するデータを取得できます。
$ curl -X PUT -d '{"Datacenter": "dc1", "Node": "google", "Address": "www.google.com", "Service": {"Service": "search", "Port": 80}}' http://127.0.0.1:8500/v1/catalog/register
HTTP APIに加えて、サービスの説明とともにエージェント構成ファイルを使用できます。
第2部では、Consulサービスに関するストーリーを完了します。つまり、次の機能について説明します。
- DNSインターフェイス。
- HTTP API
- ヘルスチェック。
- K / Vストレージ。
そしてもちろん、Consulとの作業をまとめます。