web-dev-qa-db-ja.com

分散システムでのハートビートのベストプラクティス

過去のシステムでは、外部データプロバイダー(ソースと呼ぶ)が定期的にハートビートをJavaアプリケーション(クライアントと呼ぶ)に送信していました)。ハートビートが失敗した場合、システムはシャットダウンします(重要なアプリケーションで古いデータを提供することは避けてください)データとハートビートの両方が同じチャネルを使用しているため、これは簡単で、信頼性が高くなります。

それ以来、Javaクライアントがいくつかのマイクロサービスに分割され、データがサービス間でkafkaキューを介して部分的に流れるようになりました。

重要なことは、最も上流のシステム(宛先と呼ばれる)でも確実にハートビートを取得できることです。

別のチャネルを介してハートビートを送信し続けると、いずれかのマイクロサービスまたはkafkaキューで障害が発生すると、宛先へのデータフローが中断されますが、ハートビートは流れ続けます中断することなく-ハートビートを持つという目的全体を失敗させる

私が考えている1つの解決策は、すべてのサービスとkafkaキューを介してハートビートをプッシュし、それらがデータ自体と同じパスを取るようにすることです。いずれにしても、最良のパターン/デザインは何ですか。このような分散システムでハートビートを再実装するための基準は?

5
senseiwu

あなたの解決策は明白なものです。各サービスがそのソースの1つからハートビートを受信するとき、ソースと時間をメモし、そのサービスがハートビートを(シンクに)送信するとき、すべてのソースが生きていることを確認します。

オプションのソースがある場合、「生きている私のソース」はよりトリッキーになりますが、おそらくデータの処理方法でこれに対処しているので、ハートビートはそのアプローチと一致する必要があります。

ServiceAServiceBの3つのインスタンスのいずれかにデータを送信できる場合、ハートビートをつのインスタンスすべてに送信する必要があります。

ServiceCServiceDの3つのインスタンスのいずれかからデータを受信した場合、anyDが送信された場合、そのServiceDソースから最近のハートビートが確認されています

4
Caleth

はい。私が理解しているように、あなたはこれを持っています:

DataSource - pushes occasional messages to Clients

Client - Listens for datasource messages

問題:DataSourceが断続的にメッセージを送信するため、データソースが停止した場合、クライアントは気付かずに、古いデータと現在無効なデータを表示し続けます。

古いソリューション:

DataSource - pushes occasional messages to Clients, 
    PLUS a regular small 'heartbeat' message

Client - Listens for DataSource messages and the 'heartbeat'. 
    If the heartbeat isn't received X seconds after the last one, 
    we know the DataSource has died and can take action.

新しい状況:

DataSource - pushes occasional messages to intermediate clients,

Load Balanced MicroService(1) - listens for datasource mesages 
    and pushes messages to next in chain

Load Balanced MicroService(n) - listens for MicroService(n-1) 
    and pushes messages to next in chain

Client - Listens for MicroService(last) messages, but the
    heartbeat is lost in the ether

ソリューション:

MicroServicesは古いクライアントのように動作し、データソースが失敗したときにリスナーに報告する必要があります。

ただし、メッセージは負荷分散グループの単一のマイクロサービスによって処理されますが、ハートビートはそれらすべてによって処理される必要があります。したがって、ハートビートはfanoutルーティングを使用し、メッセージはワーカーキューを使用する必要があります。

ただし、各ワーカープロセスが独自のハートビートを公開するため、このパターンを連鎖的に続けるのは困難です。

ワーカーを他の世界から隠すルーティングサービスがある、より高度なルーティングの形式をお勧めします

enter image description here

ここで、ルーターワーカーは受信キューをリッスンし、ワーカーのプールにタスクを送信します。完成した作品を受け取り、引き渡します。個々の労働者を隠す。死亡したり、作業を完了するのに時間がかかりすぎたり、負荷がかかったときに新しいワーカーを起動したりするワーカーに対処できます

あなたの場合、それはまたハートビートを処理することができます。ダウンストリームハートビートが、送信するメッセージの代表であることを確認します。

1
Ewan

「ハートビート」とは、間違った問題を解決することです。

マイクロサービスのコンシューマーは、いずれかのマイクロサービスが停止したときに古いデータが提供されないようにする必要があります。

実際、現在の設定であっても、ハートビートは本当に問題を解決していません。

データベースがダウンした場合、データベースに接続しない「ハートビート」は、アプリケーションがまだ稼働していることを報告します。私は数年前にこれに遭遇しました。さらに悪いことに、各マイクロサービスが同じデータベースに接続するとは限りません。

マイクロサービスを呼び出すたびに、呼び出し(ソース)を行った時点から、マイクロサービスが使用するすべてのリソースに対して発生する可能性のある壊滅的な問題に対するエラー処理が必要です。マイクロサービスを呼び出す必要があるときに、マイクロサービスのデータベースがダウンしているかどうかは明確にはわかりませんが、ある種のHTTPエラー応答が返されます(4xxまたは5xx)。また、応答が返されない場合、マイクロサービスを使用するアプリケーションは、通話中に適切なタイムアウトを必要とします。

パズルの最後のピースは、テクノロジエコシステム全体の適切なサーバー監視であり、マイクロサービスのコンシューマの維持を担当する人々に問題を通知する明確で効率的な手段です。

サービス指向/マイクロサービスアーキテクチャへようこそ。物事はうまくいくとうまくいきますが、カオスが君臨するとき、それは注がれます。

0
Greg Burghardt