Pub-Subモデル
少し夢を見て、Pub-subシステムをゼロから開発してみましょう。 結果は最も明白なモデルであり、将来、特定の実装の機能と考えられる問題を理解するのに役立ちます。
システムのメインビジネスプロセスは次のようになります。
- サブスクライバーはメッセージをサブスクライブします 。
- 出版社はメッセージを作成します 。
- 発行者は、システムにメッセージを発行します 。
- メッセージはシステムにしばらく保存されます 。
- システムは、すべてのサブスクライバーにメッセージを送信します 。
- サブスクライバーはメッセージを受け入れます 。
- サブスクライバーはメッセージを処理します 。
これに下線を引いて、上記のビジネスプロセスの参加者を強調しました。
- 出版社 いくつかあるかもしれません。
- 加入者 通常は複数ありますが、まったく存在しない場合があります。
- システム。 これがpub-subシステムです。
すべての関係者はメッセージで作動します 。 メッセージは送信データです。 通常、これはデータがシリアル化されるバイトの配列です。
次のメッセージ操作をリストしました(太字で表示):
- 購読する
- 作成する
- 公開する
- 店
- 提出する
- 受け入れる
- 処理
キューと非同期
モデルのどこにもキューはありませんでした。 pub-subの定義にも記載されていません。 また、非同期性はどこにも言及されていません。
しかし、キュー/キューなしでは、pub-subの実装はほとんど不可能です。 メッセージを公開した直後に送信しようとすると、多くの問題が発生します。 たとえば、何千人ものサブスクライバーにメッセージをどのくらい迅速に送信しますか? サブスクライバーが前のメッセージを処理する時間がない場合はどうなりますか? 前のメッセージがまだ送信されていない間に新しいメッセージが発行された場合はどうなりますか?
理論的には可能ですが、キューのないpub-sub実装を見たことはありません。
だから、行。 キューは、「先着順」の原則に基づいて動作する一時的なメッセージリポジトリです。 繰り返しますが、pub-subの定義では、メッセージの順序を維持する必要はありませんが、これは通常暗示されています。
キューをどこに配置しますか? この問題は、今後の議論を通じて金の糸になります。
実装の問題
さて、おそらく、私たちはビジネスプロセスについての質問を定式化し始めるでしょう:
- パブリッシャーとサブスクライバーのアドレスはどこにどのように保存されますか?
原則として、プロセスの参加者は誰でもアドレスを保存できます。 ただし、通常、システムはブローカーとして機能し、すべての住所を自宅に保存します。
- サブスクリプション、どのようなものですか?
サブスクリプションには、サブスクライバのアドレスが含まれます 。 さらに、メッセージがこのサブスクリプションに一致するかどうかを決定する一種のフィルターである「 メッセージクラス 」が示されます。 ここでは出版社の住所は必要ありません。
- サブスクリプションをいつでも追加または削除できますか、またはそのためにシステムを停止する必要がありますか?
サブスクリプションを追加/削除した場合、すでに公開されていて送信待ちのメッセージにどのような影響がありますか?
- メッセージ形式は重要ですか?
ほとんどの場合、メッセージはシリアル化され、パッケージに配置されます。 パッケージとともに、追加のパラメーターを転送できます。これらのパラメーターは、パッケージのヘッダーに配置されます。
- サブスクリプションによってメッセージはどのようにフィルタリングされますか?
通常、メッセージは発行段階でサブスクリプションによってすぐにフィルタリングされます。 サブスクライバにメッセージを送信する段階でのみメッセージがフィルタリングされる場合があります。 サブスクライバ側でメッセージがすでにフィルタリングされている場合があります。
- サブスクリプションフィルターとは何ですか?
サブスクリプションフィルタは、名前空間、キーのセット、またはRegEx式のような階層にすることができます。
- システムまたはサブスクライバーがメッセージを受信できない場合はどうなりますか?
システムまたは加入者は、受け入れを拒否したり、警告なしにメッセージを削除したり、単にフリーズしたり失敗したりする場合があります。
- 失敗した場合、メッセージを再送信する必要がありますか?
再試行は、受信側が一時的に利用できない場合の標準ソリューションです。 ここでのキーワードは「一時的」です。 受信側または伝送チャネルが継続的に機能しなくなった場合、送信を繰り返すことは何の助けにもならず、システム/通信チャネルに過負荷をかけるだけです。
- メッセージを再送するためのアルゴリズムをカスタマイズできますか?
信頼性の低い通信チャネルでは、この問題が主なものの1つである可能性があります。 再試行の回数、試行の間隔を変更できますか? 試行間隔を設定するためにどのアルゴリズムが使用されますか?
- メッセージの持続時間は?
サブスクライバーが長時間メッセージを受け取らない場合、サブスクライバーは何をすべきですか? 無期限に保存するか、一定の間隔で削除する必要がありますか?
- 誰がメッセージの送信を開始しますか?
加入者は、時々新しいメッセージをシステムに問い合わせるか(ポーリングモード)、システム自体が加入者に新しいメッセージを送信します(プッシュモード)。 前者の場合、加入者はシステムのアドレスを知っている必要があり、後者の場合、システムは加入者のアドレスを知っている必要があります。 2番目のケースでは、システムはそのリソースとデータ伝送チャネルのリソースの両方をより経済的に使用します。
- サブスクライバーがメッセージで過負荷になるとどうなりますか?
彼は新しいメッセージを受信して送信者に警告を送信するために入口を閉じますか、それとも静かにメッセージを無視しますか? または、加入者がリソースを増やす(スケールする)ことはできますか?
プロジェクトでpub-subを使用し、このために既存のpub-subシステムのいずれかを選択する場合は、これらの問題を確認してください。 これらのいずれかが重要な場合は、答えを見つけてください。
実装の詳細
例として、このクラスの最も人気のあるプログラムを使用したPub-Sub実装を検討します。 このリストで何かを変更する必要があると読者が判断した場合、これについて一度説明します。 テンプレートの理論的な議論を続けるのではなく、なぜこれを行うのですか? 私は、実装の例が、むき出しの理論よりも理解にとって重要であると感じています。
だから今リストにあるもの:
- Microsoft Azure ServiceBusのトピック
- Microsoft Azure EventHub
- Microsoft BizTalk Server
- うさぎ
- ZeroMQ
- microServiceBus
- レディス
Azure ServiceBusのトピック
システム全体はMicrosoft Azureにあります。 実装は、 メッセージブローカーモデルに基づいた古典的なものと言えるかもしれません。
Pub-subシステムは、集中型の有料サービスであり、すべてのメッセージが通過するブローカーです。 すべてのパブリッシャーとサブスクライバーはここに登録され、すべての資格情報もここに保存されます。 サブスクライバーはここでサブスクリプションを登録します。 すべてのメッセージはここに到着し、SQL Serverに基づいて実装されたキューに分類されます。 サブスクリプションごとに、メインキューに格納された実際のメッセージへのポインターを格納する一種のカーソルである仮想キューが作成されます。 サブスクリプションフィルターによって選択されたメッセージは、仮想キューに入ります。 サブスクライバーが次のメッセージを自分で要求する(ポーリング)か、システムがサブスクライバーに新しいメッセージを通知する(プッシュ)。 サブスクライバーがメッセージを受信すると、メッセージポインターが仮想キューから削除されます。 メッセージがすべての仮想キューから削除されると、システムからメインキューから削除されます。
Microsoft Azure EventHub
EventHubは、従来の実装とは大きく異なります。 主な違いは、EventHubはサブスクリプションを登録または保存せず、仮想キューを作成または保存しないことです。 受信したメッセージは、単に線形リストとしてシステムに保存されます。 それらは一定時間保存され、その後システムによって削除されます。 サブスクライバーはすべてのメッセージにアクセスできます。 サブスクライバーはメッセージを自分でフィルター処理し、カーソルをリストに保持します。 一方で、これは加入者に追加機能を配置します。 一方、EventHubは優れたパフォーマンスを提供するサブスクリプションサポートから解放されました。 また、サブスクライバーはいつでもリストに戻ってメッセージを読み直すことができるため、信頼性の問題に対する異なるアプローチが可能になります。 パブリッシャーからサブスクライバーのほぼ完全な独立が達成されます。
EventHubのサブスクリプション操作はnull操作です。 クライアントはいつでもメッセージの読み取りを開始できます。
Microsoft BizTalk Server
BizTalkは過去20年にわたって存在しているため、革新的なアプローチを期待するべきではありません。 基本的に、MessageBoxと呼ばれるそのPub-subエンジンは、Azure Topicsの前身です。 違いは、アダプターを介してアクセスされることです。 API関数を呼び出してメッセージを発行または受信するだけではなく、アダプターを使用する必要があります。 アダプタは、パブリッシャーとメッセージ受信者の両方の役割を果たします。
うさぎ
RabbitMQは AMQPプロトコルのアイデアに基づいていますが、最新バージョン(1.0)ではなく、以前のバージョン(0-8および0-9-1)に基づいています。 これらのバージョンでは、いわゆる交換がサポートされていますが、AMQPの開発者はバージョン1.0で拒否しました。 交換モデルは、ブローカーのpub-subをエレガントに実装します。これはRabbitMQです。
ZeroMQ
ZeroMQはAMQPのアイデアの後継です。 AMQPバージョン1のディスカッションプロセスが停止したときに、AMQPの作成者の1人がZeroMQを作成しました。 ZeroMQは、pub-subの使用など、超高速メッセージングシステムを実装するための興味深いアイデアの1つです。
ZeroMQには一元化されたサービスがありません。 Pub-subシステム全体は、パブリッシャーおよびサブスクライバーコードの一部として実装されます。 ZeroMQは単なるキューイングライブラリです。 最も単純なモデルでは、サブスクライバーおよびパブリッシャープログラムがローカルキューを作成します。 サブスクライバーは明示的にパブリッシャーのアドレスに接続します。その後、パブリッシャーのキューからのメッセージがサブスクライバーのキューに到着し始めます。 キューは、中間ブローカーなしで、パブリッシャーおよびサブスクライバープログラムのアドレススペースに配置されます。 システムは個別のサービスでは表されませんが、パブリッシャーとサブスクライバーの間に広がるかのようです。
一方では、パブリッシャーまたはサブスクライバーがシャットダウンすることを決定した場合、彼のキューからのメッセージは単に消えます。 一方、このような実装は最大のメッセージレートを提供します。
ZeroMQのキューはメモリに保存されるため、パフォーマンスは最大になりますが、信頼性は低下します。
ZeroMQは、より複雑な構成も実装します。 たとえば、ブローカーでpub-subを作成できます。 さらに、ZeroMQを使用すると、従来のPub-subシステムには類似物がないさまざまなアーキテクチャを作成できます。 たとえば、分散ブローカー用のさまざまなオプションを作成できます。 ZeroMQ Webサイトで最も成功しているpub-subの説明の 1つを読むことをお勧めします。pub -subの基本から始まり、 より複雑なモデルで終わります 。 それには多くの時間がかかりますが、例えば、pub-subの多くの重要な側面に目を向けました。
microServiceBus
新しいpub-sub実装の1つ。 いくつかの興味深い解決策のため、リストに追加しました。 Azure ServiceBusトピックのmicroServiceBusに基づいています。
興味深いことに、パブリッシャーとサブスクライバーのコードはAzureに保存されています。 さらに、このコードは自動的にダウンロードできます。 コードはNode.jsに実装されているため、プラットフォームに依存しません。 Node.jsは、ほぼすべてのオペレーティングシステムとデバイスで動作します。 Node.jsが機能するデバイスは、パブリッシャーまたはサブスクライバー、またはその両方を同時に使用できます。
BizTalk Serverの例に従って、microServiceBusは多くのシステムとプロトコル用のアダプターを実装します。 ただし、BizTalkとは異なり、アダプターはAPIへの便利な追加機能です。
microServiceBusは、開発者に焦点を合わせているという点でZeroMQに似ています。
ZeroMQと同様に、マルチプラットフォームです。ただし、ZeroMQマルチプラットフォームはライブラリを多くの言語に移植することに基づいており、ベースライブラリはCで作成されています。マルチプラットフォームmicroServiceBusはNode.jsが多くのオペレーティングシステムに移植されているという事実に基づいています。
microServiceBusは、システム統合とデバイス統合(IoT)の両方に焦点を当てています。
レディス
Redisは実際にはpub-subシステムではなく、 キーと値のデータストレージです。 しかし、意外にも古典的なpub-subをうまく実装し、驚くべきパフォーマンスを示しています。
Redisはローカルにインストールすることも、分散サービスとしてインストールすることもできます。 メッセージをディスクに保存する機能を追加できます。
システム選択
pub-subシステムをより実用的な側面から見ようとすると、プロジェクト用、仕事用のシステムを選択するという問題が避けられません。 私はこの質問に答えようとはしていません。答えを探すための概要を説明するだけです。 まず、pub-subシステムは、この記事で収集したシステムよりもはるかに大きいです。 第二に、どんな場合でも、正しいアクセントを持っているふりをしないでください。
一般リストから特別なものとして際立っているシステムに焦点を当てます。
比較表はこちらです。
開発環境
BizTalk Serverは、Visual Studioでのみ使用できます。 システムのさまざまな部分を作成するには、多数のエディターが使用されます。
他のシステムの開発は、基本的にコードとシステムAPIを使用した通常の作業に帰着します。
開発言語
これは、パブリッシャーおよびサブスクライバー向けのプログラムの開発を指します。クライアントコードと呼びます。 システムのコアは通常、既製のサービスの形で提供されます。システムを機能させるには、パブリッシャーとサブスクライバーのプログラムを追加する必要があります。
Redis、ZeroMQ、RabbitMQのクライアントコードは、多数の言語で開発できます。 C#、Java、Python、PHP、JavaScript / Node.js、Scala、Rubyなど、産業システムに使用されるすべての言語を使用できます。
ZeroMQでは、ほとんどの言語はCで記述された元のライブラリのシェルとして実装されています。C#、Java、Erlang、およびJavaScriptの元のライブラリもあります。 しかし、Cの元のライブラリの機能はわずかに遅れています。
Azure ServiceBus TopicsおよびAzure EventHubには、C#およびREST APIがあります。
microServiceBusクライアントコードはNode.jsでのみ記述されていますが、これは欠点よりも強みです。
システムコアの実装
Azure ServiceBus TopicsおよびAzure EventHubシステムは、Microsoft AzureクラウドでホストされるSaaSサービスとして実装されます。 microServiceBusは、Azure ServiceBusトピックの上で実行されます。
ZeroMQには既製のブローカー部分はありませんが、非常に簡単に実行できます。 また、あらゆる機能を備えた複雑なブローカーを作成できます。 優れたプログラマーは、このためにZeroMQを選択することがよくあります。
RabbitMQおよびRedisサービスは、バイナリおよびソース形式で提供され、Windows、Linux、Mac、Unixの任意のサーバープラットフォームにインストールできます。 ZeroMQは、どのプラットフォームにもインストールできます。
BizTalk Serverは、Windowsサービスで動作する大規模なSQLコードと.NETコードの形式で実装され、Windowsでのみ動作します。 BizTalkのライセンスだけでなく、WindowsおよびSQL Serverのライセンスも必要です。
信頼性と成熟度
BizTalk Serverはこのカテゴリで際立っています。 彼は、それに基づいたシステムが何年もメンテナンスなしで機能しているという事実で知られています。 そのカーネルのコードは実質的に変更されていないままで、長年にわたってエラーが修正されています。
ZeroMQとRedisはかなり新しいシステムであり、常に改善されています。 これにより、信頼性の点で正確にその特異性が課せられます。 それらに基づいた大規模なシステムは知られていますが、そのようなシステムを作成するには優秀なプログラマーが必要です。
Azure TopicsとEventHubは新しいシステムですが、Microsoftはその背後にあるため、信頼性に関する苦情はありません。
システムが登場したばかりなので、microServiceBusに関する情報はまだありません。
メッセージキューをディスクに格納するシステムは、メモリにのみメッセージを格納するシステムよりも信頼性が高いことに注意してください。
性能
ZeroMQはここで際立っています。 場合によっては、バッチ処理のおかげで、TCPよりもさらに高速にメッセージを送信します。
ZeroMQの後にはRedis、次にEventHubが続きます。
拡張性
また、ZeroMQは、アーキテクチャとリソース要件が低いため、最高のスケーラビリティを実現します。 ただし、システム設計には特別な注意を払う必要があります。 ZeroMQのドキュメントにはスケーラブルなシステムの多くの例が記載されていますが、大きな変更を加えることなく実装できる既製の設計を見つけることはまずありません。
価格
BizTalk Serverは、リストの中で最も高価なシステムです。 ただし、pub-subはその機能のごく一部であり、まったく異なる基準に従ってBizTalkを選択することを理解する必要があります。
これらのシステムの一部は、オープンソースシステムです。 極端な場合、あなたは有料サポートにお金を使うでしょう。
シンプルさ
ZeroMQを使い始めるのに数分しかかかりません。 Redisにはもう少し時間がかかります。 Azure ServiceBusトピック、microServiceBus、RabbitMQ、およびAzure EventHubも簡単に開始できます。
BizTalk Serverはすべての面で複雑ですが、その成熟度のおかげで、システムに取り残される可能性は低く、豊富な経験を持つ優れた専門家を常に見つけることができます。
AzureまたはRabbitMQで動作するシステムは、見かけほどセットアップやスケーリングが簡単ではありません。 クラスター構成で構成されたブローカーには、知識だけでなく、経験も必要です。
システムの複雑さは、システム内のノードの数よりもはるかに速く増加します。