EIP / Point-to-Point Channel


Point-to-Point Channel

ひと言要約

1対1のやり取りをチャネルで制御。

要約

アプリケーションはRPCをするか文書を転送するのにMessagingを使ってる。

センダーは、どうやってレシーバーがちゃんと文書を受け取るか、呼び出しを処理しているか、を知ることができる?
  • RPCの長所として、ひとつのリモートプロセスとして実行されるというものがあげられる。
    • レシーバーは処理を行うか否か(例外発生の場合も)に落ち着く。
    • たった一度だけ呼ばれれば、たった一度だけ処理を実行する。
  • メッセージの場合は、いったん呼び出しがMessageとしてパッケージングされてMessage Channelに置かれると、多くのレシーバーがチャネル上で見ることができる。


  • メッセージングシステムは、ふたつ以上のレシーバーがひとつのチャネルをモニタリングするのを防ぐことができる。
    • が、複数のレシーバーに送りたいセンダーを制限することになる。
  • チャネル上のすべてのレシーバーは、それらのただ1つだけが処理を実行するということを協調できる。
    • が、それは複雑で、通信のオーバーヘッドを生み出してしまい、独立したはずのレシーバー間での結合度が増大化してしまう。
  • 平行に処理される複数のメッセージであれば、ひとつのチャネルに複数のレシーバーがいるのは構わない。
    • が、どのレシーバーもあらゆるメッセージを処理できなければならない。
Point-to-Pointチャネル上でメッセージを送ると、ひとつのレシーバーのみが特定のメッセージを受けとれる。(P.103の図を参照)

Point-to-Pointチャネルは、ひとつのレシーバーのみが受け取ったあらゆるメッセージを消費することを保証する。

  • チャネルは複数のメッセージをコンカレントに消費できるよう複数のレシーバーを持てるし、ある特定のメッセージはその中のひとつだけにする、といったこともできる。
  • レシーバーは互いに協調する必要はない。


  • チャネルが複数のコンシューマーを持つなら、Competing Consumersであり、チャネルはそれぞれのメッセージをひとつのコンシューマーが消費するよう保証する。
  • 複数のコンピュータ、アプリケーション、コンシューマーに横断的に負荷分散できるので、この設計はメッセージの消費と処理をかなりスケーラブルなものにする。


関連パターン

Example

株の売買システム

  • 特定の売買を行うリクエストのメッセージはPoint-to-Pointチャネル上に置かれる。

Example

JMS Queue

  • JMSでは、Point-to-PointチャネルはQueueインターフェイスを実装する。
    • センダーはQueueSender?を使用してメッセージを送る。
    • レシーバーはQueueReceiver?を使用してメッセージを受信する。

QueueSender?を使った例

Queue queue = // obtain the queue via JNDI
QueueConnectionFactory factory = // obtain the connection factory via JNDI
QueueConnection connection = factory.createQueueConnection();
QueueSession session = connection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
QueueSender sender = session.createSender(queue);

Message message = session.createTextMessage("The contents of the message.");

sender.send(message);

QueueReceiver?を使った例

Queue queue = // obtain the queue via JNDI
QueueConnectionFactory factory = // obtain the connection factory via JNDI
QueueConnection connection = factory.createQueueConnection();
QueueSession session = connection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
QueueReceiver receiver = session.createReceiver(queue);

TextMessage message = (TextMessage) receiver.receive();
String contents = message.getText();

補足:JMS1.1はPoint-to-PointとPublish-Subscribeのドメインを統一しているので、コードはもっとシンプルにできる。(らしい)

Example

.NET Message Queue

  • .NETでは、Point-to-PointチャネルはMessageQueueクラスを実装する。
  • .NETのメッセージングを実装しているMSMQでは、バージョン3.0以前はPoint-to-Pointメッセージングのみをサポートしていたので、.NETもそう。
  • JMSがコネクションファクトリ、コネクション、セッション、センダー、レシーバー、キューの責務を分けていたのに対し、MessageQueueはそのすべてを担う。

メッセージ送信は次のような感じ

MessageQueue queue = new MessageQueue("MyQueue");
queue.Send("The contents of the message.");

メッセージ受信は次のような感じ

MessageQueue queue = new MessageQueue("MyQueue");
Message message = queue.Receive();
String contents = (String) message.Body();