EIP / Durable Subscriber


Durable Subscriber (永続サブスクライバ) 

一言要約

パブリッシュ·サブスクライブチャネルにおいて、Durable Subscriberを使うと、レシーバがシステムクラッシュやその他の理由でリスニングできなかった間のメッセージを、再接続時に受け取ることができる。

要約

アプリケーションでは、パブリッシュ·サブスクライブのチャンネルでメッセージを受信しています。


どのように、サブスクライバは、リスニングしていない間に失われてしまうメッセージを回避することができるのか?

なぜこのようなことが問題なのか?メッセージがチャネルに追加されると、それが消費されるか、有効期限が切れるか(メッセージの有効期限を参照)、またはシステムがクラッシュするまで(保証付き配信を使用している場合を除きます)存在します。これは、ポイントツーポイントチャネル上のメッセージにも当てはまりますが、パブリッシュ·サブスクライブのチャンネルではいくらか異なります。

メッセージがパブリッシュ·サブスクライブチャンネルで公開されると、メッセージングシステムはサブスクライバにメッセージを配信する必要があります。サブスクライバがメッセージを受信することは、メッセージがパブリッシュされたときのチャネルを誰がサブスクライブしているかに完全に依存しています。メッセージが発行されたとき、レシーバがサブスクライブしていない場合、レシーバは後サブスクライブしたとしても、そのメッセージを受信しない。

多くの場合、アプリケーションは、切断後にパブリッシュされたメッセージは無視することを好みます。なぜなら、切断したことというのは、アプリケーションが、たとえパブリッシュされたものでも興味がないということを意味するからです。たとえば、レンガを販売するB2B / Cアプリケーションは、バイヤーがレンガを要求できるチャネルにサブスクライブすることができる。アプリケーションがレンガを販売することを停止したり、一時的にレンガがなくなった場合、それはとにかく対応できない要求を受信しないようにチャンネルから切断することを決定できる。

しかし、この動作は不利になることもあります。なぜなら、"you snooze,you loose"アプローチ(訳者:←なんか意味わからないけど、有名な言葉なの?)は、アプリケーションが必要なメッセージを失う原因となる。アプリケーションのクラッシュ、または、メンテナンスのために停止する必要がある場合、実行されていない間に逃したメッセージを知りたいことがあります。メッセージングの全体的なアイデアは、送信側と受信側のアプリケーションとネットワークのすべてが同時に動作していない場合でも、通信の信頼性を実現することです。

時には、チャネルからメッセージを欲しくないので、アプリケーションは切断します。しかし、時にはアプリケーションが短時間切断しなければならないとき、、再接続したときには、彼接続経過中にパブリッシュされたすべてのメッセージにアクセスできるようにしたい。サブスクライバは、通常はどちらかに接続(サブスクライブ)または切断(退会)である。しかし、3番目の状態として、切断されている間もパブリッシュされたメッセージを受信したい状態として、非アクティブがある。

もしも、サブスクライバは、パブリッシュ·サブスクライブ·チャネルに接続していて、メッセージが公開されたときに切断されている場合に、どのようにメッセージングシステムは、サブスクライバが再接続したときにメッセージを配信するために、メッセージを保存するべきかどうかをどのように知るのでしょうか?つまり、メッセージングシステムは、どのように切断されたサブスクライバが非アクティブなのか、あるいはサブスクライブしていないのかを知るのでしょうか?

サブスクライバが切断されている間、メッセージングシステムがパブリッシュされたメッセージを保存するためには、Durable Subscriber(永続サブスクライバ)を使用します。

(図:パブリッシュ-サブスクライブを通して、Durable Subscriberにもメッセージを送っている)

Durable Subscriptionは、非アクティブのサブスクライバのためにメッセージを保存し、サブスクライバが再接続するときに、これらの保存されたメッセージを配送する。この方法では、サブスクライバは、それが切断された場合でも、任意のメッセージを失うことはありません。Durable Subscriptionは、サブスクライバがアクティブな間(例えば、接続されている間)は、サブスクライバまたはメッセージングシステムの動作に影響を与えません。接続しているサブスクライバは、そのサブスクリプションが永続か非永続的であるかどうかに関わらず同じように機能します。違いは、サブスクリプションが切断された場合の、メッセージング·システムの動作方法である。

Durable Subscriberは、パブリッシュ·サブスクライブチャンネル上の単なるサブスクライバです。しかし、サブスクライバがメッセージングシステムから切断されると、それは非アクティブになり、それが再びアクティブになるまで、メッセージングシステムはそのチャンネルに公開されたメッセージを保存します。

(図:Durable Subscriberのシーケンス図)

Durable Subscriptionのシーケンス

サブスクライバであるためには、Durable Subscriberは、チャネルへのサブスクリプションを確立する必要があります。いったん、それはその接続が閉じられたときに、それが非アクティブになります。サブスクライバが非アクティブである間、パブリッシャはメッセージを発​​行します。もしも、サブスクライバが、non-durableであった場合は、このメッセージを見逃すことでしょう、しかし、それはDurable(永続性)があるので、メッセージングシステムは、このサブスクライバのために、このメッセージを保存します。

サブスクライバがもう一度アクティブになって、再サブスクライブすると、メッセージングシステムがキューに入れられたメッセージ提供します。サブスクライバは、メッセージを受信し、それを処理(おそらくアプリケーションにメッセージを委譲)する。サブスクライバがメッセージの処理を介して行われたら、それはそれ以上のメッセージを受け取りたくない場合、その接続を閉じて、それは再び非アクティブになります。そしてもはや、メッセージを保存することを、メッセージング·システムに望んでいないので、サブスクライブを解除する。

Durable Subscriberが決して解除しない場合に何が起こるか?

非アクティブなDurable Subscriptionは、メッセージを保持し続けるでしょうか?つまり、サブスクライバが再接続するまで、メッセージングシステムが公開されたメッセージをすべて保存するでしょう。しかし、サブスクライバが長時間再接続しない場合、保存されたメッセージの数が過剰になりえます。メッセージの有効期限は、この問題を軽減できます。メッセージング·システムはまた、非アクティブなサブスクリプションのために保存するメッセージの数を制限することができる。

例:株式取引

株式売買システムは、株式価格の変動を放送するパブリッシュ·サブスクライブ·チャネルを使用することができる。毎回銘柄の価格が変更されると、メッセージが公開される。あるサブスクライバは、特定の株式の現在の価格を表示するGUIであるかもしれません。別のサブスクライバは、特定の銘柄のために一日の取引レンジを格納するデータベースであるかもしれません。

彼らは株式の価格の変更時に通知されるために、両アプリケーションは、価格変更チャネルを購読する必要があります。GUIのサブスクリプションは、現在の価格を表示しているので、non-durableであることができます。GUIは、チャネルへの接続を失いクラッシュした場合、GUIが表示できない価格の変更を保存しても意味がありません。一方、価格帯データベースはDurable Subscriberを使用する必要があります。実行されている間、これまでの範囲を表示することができる。もしも、その接続を失った場合、再接続時には、発生した価格の変更を処理し、必要に応じて範囲を更新することができる。


例:JMS永続サブスクリプション

JMSはTopicSubscriber?のためにDurable Subscriptionをサポートしています。[JMS11、pp.80-81]、[Hapner、pp.61-63]

Durable Subscriptionのもつ1つの課題は、完全に新しいサブスクライバと、再接続されている古いサブスクライバを区別することです。JMSでは、Durable Subscriptionは、次の3つの基準によって識別されます。 1。トピックにサブスクライブされている 2。接続のクライアントID 3。そして、サブスクライバのサブスクリプション名

接続のクライアントIDは、接続ファクトリがメッセージングシステムの管理ツールを使用して作成されたときに設定されているそのコネクション·ファクトリのプロパティです。サブスクリプション名は、それぞれのサブスクライバごとに(特定のトピックとクライアントIDのために)一意である必要があります。

Durable SubscriberはSession.createDurableSubscriber?のメソッドを使用して作成されます:

   ConnectionFactory factory = // ファクトリを手に入れる
   // クライアントIDを持つファクトリ
   Connection connection = factory.createConnection();
   / /接続は、ファクトリと同じクライアントIDを持っている
   Topic topic = // obtain the topic
   String clientID = connection.getClientID(); // あなたが興味があれば確認
   String subscriptionName = "subscriber1"; // サブスクリプションと一緒のUID
   
   Session session =
       connection.createSession(false, Session.AUTO_ACKNOWLEDGE); TopicSubscriber subscriber =
       session.createDurableSubscriber(topic, subscriptionName);

このサブスクライバは今アクティブになります。それは、(non-durableのような)トピックにパブリッシュされたメッセージを受信します。それを非アクティブにするには、以下のように閉じます、:

   subscriber.close();

サブスクライバは現在切断され、したがって非アクティブされています。そのトピックにパブリッシュされたメッセージは、このサブスクライバのために保存され、それが再接続したときに配信されます。

再びサブスクリプションをアクティブにするには、同じトピック、クライアントID、およびサブスクリプション名を持つ新しいDurable Subscriberを作成する必要があります。コー​​ドでは、接続ファクトリ、トピック、およびサブスクリプション名は前と同じでなければならないことを除けば、前と同じです。

Durable Subscriptionを確立し、それに再接続するためのコー​​ドは同じであるので、唯一メッ​​セージングシステムは、このDurable Subscritptionが既に確立されたか新しいものかどうか知っています。一つの興味深い結果は、サブスクリプションに再接続しているアプリケーションは、以前切断された同一のアプリケーションではないかもしれないことである。新しいアプリケーションは、同じトピック、同じ接続ファクトリー(と、同じクライアントID)と、古いアプリケーションと同じサブスクリプション名を使用している限り、メッセージングシステムは、2つのアプリケーションを区別できないため、古いアプリケーションに配信されていなかったすべてのメッセージの配信を新たなアプリケーションへ配信するでしょう。

一度、アプリケーションがトピックのDurable Subscriptionを持っていたら、それはサブスクライバがその接続を閉じていても(または、それがクラッシュしてメッセージングシステムは、それのためにサブスクライバの接続を閉じた場合でも)、そのトピックにパブリッシュされたすべてのメッセージを受信する機会があります。この非アクティブなサブスクライバのためにキューイングメッセージをメッセージング·システムを停止するには、アプリケーションが明示的にDurable Subscriptionを退会しなければなりません。

   subscriber.close(); / /サブスクライバが非アクティブになり、メッセージが保存されます
   session.unsubscribe(subscriptionName); / /サブスクリプションが削除される

サブスクライバが登録解除されると、サブスクリプションは、トピックから削除され、メッセージは、もはやこのサブスクライバに配信されません。

関連パターン: Guaranteed Delivery, Message Expiration, Point-to-Point Channel, Publish-Subscribe Channel

担当者のつぶやき

みんなの突っ込み