私は、Webサービス(WCF、Axis2)、ESB、SOAを含むさまざまな通信技術/アーキテクチャ/パターン/実装(流行語)を研究しており、メッセージングに関してJMSについてもっと知りたいと思っていました。
概念的には、JMSは単純に聞こえます。私の見解は、パブリッシャーからのメッセージを管理し、適切なサブスクライバーにルーティングする中間ブローカーであるということです。これは、メッセージがパブリッシュされたときにキューに入れ、受信時にメッセージをデキューすることによって行われます。
質問1:JMSの私の基本的な理解は正しいですか?
テクノロジーについて読むときに私を悩ませるものの1つは、特定のレベルの(意図的または意図的ではない)手振りが機能について行われるときです。
私の基本的な理解に基づいて、メッセージを送受信するには、JMSプロバイダーが実行されている必要があります。パブリッシングに関する私の仮定は、JMSプロバイダーはメッセージがパブリッシュされるまで単に待機し、次にそれをキュー(実装に応じてメモリーまたはデータベースに依存)に格納することです。ただし、受信がどのように機能するかはよくわかりません。
質問2:使用可能なメッセージがない場合、受信は(通常)ブロックしますか?
質問2b:その場合、どのようにしてブロッキングが達成されますか?クライアントはメッセージを継続的にポーリングしますか?サーバーはメッセージが公開されるまで応答しません(タイムアウトなしでこれはどのように機能しますか?)プロバイダーは通話を開始しますか?受信者に?
質問2c:そうでない場合、どのようにして、パフォーマンスに影響を与えることなく、メッセージがタイムリーに受信されることを確実にしますか?
基本的な説明では、メッセージが失われないように集中管理されるように、単一のJMSプロバイダーに傾いているようです。スケーリングが問題であることがわかります。
質問3:JMSはどのように拡張されますか?
スケーリングすると、どの物理サーバーがメッセージを受信するかに関係なく、単一のメッセージがすべての適切なサブスクライバーに確実に配信されるようにするための複雑さがあることがわかります。
質問3b:JMS実装は、スケーリングされた環境で信頼できる配信をどのように保証しますか?
これらの質問はJMSに関連していますが、すべてのメッセージングインフラストラクチャに当てはまる可能性があることに注意してください。 JMSに固有の回答だけでなく、より一般的な回答や、別のテクノロジーに固有の回答も歓迎します。
JMSでの経験に基づいて、いくつかの質問に答えようとしています。
Answer 1:- JMS is Java Message Service API;これは、Javaクライアントがメッセージングフレームワークにアクセスするための統一されたインターフェイスを提供します。JMSの下APIは、JMSに準拠したメッセージングプロバイダー(WebSphere MQプロバイダーなど)です。JMSは、任意のメッセージングプロトコルを介して、宛先、つまりキューとトピックへのペイロードの転送をサポートします。これらはJMSの基本です。
どうやって仕事を受け取りますか? JMS仕様は2つの重要なクラスを提供します:MessageConsumer
およびMessageListener
。 MessageConsumer
クラスを使用すると、JMSクライアントはreceive()
メソッドのいずれかを呼び出すことにより、JMSメッセージを同期的に受信できます。この呼び出しは、メッセージが受信されるまでスレッドをブロックします。それ以外の場合は、MessageListener
のオブジェクトをMessageConsumer
に登録することにより、非同期受信を行うことができます。メッセージがローカルの宛先に到着したことを知るのはJMSProviderであり、そのジョブはポーリングメッセージコンシューマスレッドまたは非ポーリング登録メッセージリスナスレッドにメッセージを配信することです。
Answer 2:-MessageConsumer
APIには、receive()
とreceive(long timeout)
の2つのreceiveバリアントがあります。後者のバリアントは、メッセージが特定のタイムアウト期間内に到着するか、タイムアウトするまで、MessageConsumer
スレッドをブロックします。
異なるメッセージングフレームワークは、異なる方法でブロッキング機能を実装する場合があります。 JMSオブジェクトはJNDI管理オブジェクトであり、プロバイダー固有のプロキシオブジェクトはJMSクライアントに返されるため、クライアントはバックグラウンドでブロックがどのように発生しているかを認識していません。特定のメッセージングフレームワークは、特定の期間後にポーリングするメッセージコンシューマスレッドを選択できます。または、通知が送信されるまでブロックすることもできます。
特定のJMS準拠のメッセージングフレームワークに対する回答を探しているかどうかわかりません。
Answer 3:- JMSスケーリングとは、複数の物理マシン上に多数のパブリッシャー/サブスクライバー、多数の宛先を持つ能力を意味すると思います。 JMSスケーリングは、ある種のクラスタリング/フェイルオーバーをサポートするために、基盤となるメッセージングプロバイダーのサポートを必要とします。そのため、JMS仕様はスケーラビリティをサポートしていません。私がこれについて間違っている場合は私を修正しますか?たとえば、クラスタリングのサポートを提供するJMS準拠のWebSphere MQに取り組んでいます。
質問1:JMSの私の基本的な理解は正しいですか?
まず、用語を正しく理解しましょう。 _JMS Provider must be running
_とは言えません。プロバイダーはJMSサーバーを構築したエンティティであり、実行している必要があるのはJMSサーバーだからです。したがって、JMSとは、プロバイダーが実装する一連のAPI(より技術的にはインターフェース)を意味します。したがって、基本的にプロバイダーは独自のJMS実装を作成します。たとえば、Apache(provider)
によって提供される_Active MQ is a JMS server
_
パブリッシングに関する私の仮定は、JMSプロバイダーはメッセージがパブリッシュされるまで単に待機し、次にそれをキュー(実装に応じてメモリーまたはデータベースに依存)に格納することです。
ある程度正しい。従うさまざまなモデルがあります。 JMSサーバーはソケットを開いたままにします。送信側クライアントがメッセージを送信する必要がある場合は、ソケットへの接続を開いてメッセージを送信するだけです。 receiveの動作はまったく異なります。 pullとPushがあります。プッシュサーバーでは、メッセージを受信するとすぐに、ライブレシーバークライアントにメッセージをプッシュします。これは非同期モードとも呼ばれます。プルモデルでは、クライアントレシーバーはサーバーにリクエストを送信してメッセージを取得します(同期モード)。
使用可能なメッセージがない場合、receiveは(通常)ブロックしますか?
以前のポイントで述べたように、それはあなたが使用しているモデルに依存します。レシーバーはプルモデルでブロックされます(同期受信)。また、これはメインスレッドではなくSession threadで発生します。
もしそうなら、どのようにブロッキングが達成されますか?クライアントはメッセージを継続的にポーリングしますか?
はい、プルモデルの場合、クライアントは継続的にポーリングします。一般に、クライアントが終了するまでのタイムアウトがあります。
そうでない場合、パフォーマンスに影響を与えることなく、メッセージがタイムリーに受信されることをどのように保証しますか?
非同期モードを使用します。 MessageListenerを登録するだけで、サーバーでメッセージが利用可能になると、オーバーライドされたメッセージonMessage(Message msg)を受信します。
質問3:JMSはどのように拡張されますか?
それは本当にプロバイダーが心配する問題です。メッセージがすべてのサブスクライバーによって受信されたと言うとき、あなたは[〜#〜] pubsub [〜#〜]通信のモデル(その他は[〜#〜] ptp [〜 #〜])。トピックに送信されたPUBSUBメッセージでは、そのトピックにサブスクライブしているすべてのサブスクライバーに配信されます。
質問3b:JMS実装は、スケーリングされた環境で信頼できる配信をどのように保証しますか?
信頼性は?常にではない。繰り返しますが、これはユースケースによって異なります。 persistentおよびnon persistentメッセージを使用できます。永続的なメッセージの場合、メッセージはDB(ファイルまたはその他)に保存され、配信が保証されます。非永続メッセージの場合、そのような保証はありません。サーバーに障害が発生すると、メッセージが失われる可能性があります。
メッセージの配信方法には重要な違いがあるため、キューとトピックの違いに言及する必要があると思います。
キュー:1つのクライアントのみがメッセージを受信します。スケールアウトするには、たとえば、10個のクライアントをすべて同じキューに接続することができますが、特定のメッセージを受信するのはそのうちの1つだけです。クライアントが接続されていない場合、メッセージは誰かが接続するかメッセージがタイムアウトするまでキューに残ります。
トピック:すべてのクライアントが各メッセージのコピーを受け取ります。通常、多くのエンドポイントが各メッセージに関心を持つ可能性のあるサブスクライバーシナリオで使用されます。恒久サブスクライバーは、しばらくの間ダウンすることさえあります。メッセージは、サブスクライバが再び起動するか、メッセージがタイムアウトするまで保持されます。クライアントが接続されておらず、恒久サブスクライバーがない場合、メッセージはドロップされます。
JMSは、同期メソッド(タイムアウトの有無にかかわらずスレッドをブロックする受信)またはイベント駆動型コールバック(非同期メッセージリスナー)を使用したメッセージ消費をサポートします。
どの方法がニーズに適しているかを判断できますが、実際の実装を確認する必要がある場合もあります。たとえば、一部のJMS実装はreceive()のネットワークラウンドトリップを行うため、タイムアウトまたはリスナーで使用する方が適しています。
メッセージリスナのスレッドの動作とメッセージ受信の一時停止は、ブロッキング受信呼び出しの場合ほど簡単には制御できません。通常、ほとんどの制御は、タイムアウト付きのreceive()呼び出しをブロックする独自のプールを用意し、ワーカーにディスパッチすることで実現されます。
JMSには2種類のメッセージングドメインがあります。
PTPモデルでは、1つのメッセージが1つの受信者にのみ配信されます。ここでは、キューは[〜#〜] m [〜#〜]メッセージ[〜#〜] o [〜#〜]指向[〜#〜] m [〜#〜]ミドルウェア([〜#〜] mom [〜#〜])。
キューは、受信者の準備ができるまでメッセージを保持する責任があります。
PTPモデルでは、送信側と受信側の間にタイミングの依存関係はありません。
Pub/Subモデルでは、1つのメッセージがすべてのサブスクライバーに配信されます。放送のようなものです。ここでは、トピックはメッセージ指向のミドルウェアとして使用され、メッセージを保持および配信します。
PTPモデルでは、パブリッシャーとサブスクライバーの間にタイミングの依存関係があります。
[〜#〜] m [〜#〜]メッセージ[〜#〜] d [〜#〜]リヴェン[〜#〜] b [〜#〜]ean(MDB)