EIP / Message Broker


EIP

Message Broker

一言要約

  • Message Broker というのは、ひとつのアーキテクチャパターンである。(ハブアンドスポークパターン)
  • 巨大なシステムの場合、Message Broker は階層構造になる。(ちょうど、サブネットが複数あるネットワークのように)
  • 商用EAIスイートには、Message Brokerを開発・配置・監視するための便利なツールが提供されている。

要約

この章の多くのパターンは、アプリケーションがそのメッセージの最終的なあて先を意識することなく、正しいあて先にメッセージをルーティングする方法を説明している。 パターンの多くは特定のルーティングロジックに着目している。 しかしながら、全体として、それらのパターンはより大きな問題を解決している。


あなたは、どうやって送り主からメッセージのあて先を切り離して、メッセージの流れの中央制御を維持しますか?


単純な Message Channel (60) を使うことで、送り主と受信先のある程度の間接化ができます。送り主はそのチャネルだけを知っていて、受信先については知りません。 しかしながら、もし、各受信先が固有のチャネルを持っているならば、この程度の間接化は意味が小さくなります。 受信先のアドレスを知る代わりに、送り主は受信先と関連付けられた正しいチャネル名を知らなければならない。

普通のメッセージングソリューション多くは、異なる多くのアプリケーションと接続しています。 もし、各アプリケーションから別のアプリケーションに接続する個別のメッセージチャネルを作るとしたら、システム内のチャネルはすぐに管理できないほど爆発的に増えて、統合スパゲティ(integration spaghetti)に陥るだろう。(図を参照)

ポイント間通信の結果の統合スパゲティ

この図は、個別のアプリケーション間の直接的なチャネルはチャネル数の爆発を招きえて、最初の段階でのチャネルを通したメッセージルーティングの多くの利点を減じうることを示している。 このタイプの統合アーキテクチャは、しばしば、長い時間をかけて成長してきたソリューションの結果である。まず、顧客サービスシステムは会計システムとやりとりしないといけない。 そして、その顧客サービスシステムは、在庫管理システムから情報を抽出することになるし、また、配送システムは会計システムに配送料金を送る必要がある。 「もうひとつ追加すること」はソリューションの全体的な整合性をすぐに傷つけうることを簡単に見て取れる。 あるアプリケーションが明示的に他のすべてのアプリケーションと通信するとなると、システムの保守性をすぐに低下させることになる。 たとえば、もし、顧客サービスシステムにおいて顧客の住所が変更されたら、このシステムは顧客住所のコピーを保持しているすべてのシステムにメッセージを送らなければならないだろう。 新しいシステムが追加されるたびに、顧客サービスシステムは、そのシステムが住所を使用し、それに伴った変更を必要としているか知らなければならない。

Publish-Subscribeチャネル(106)は基本的なルーティングの形式のいくつかを提供している。つまり、特定チャネルを購読する各アプリケーションへ、そのメッセージを配信する。 これは、単純な放送シナリオとして働くが、ルーティングルールはしばしばより複雑である。 たとえば、やってきた受注メッセージは、受注のサイズや内容により異なるシステムへルーティングされなければならないかも知れない。 アプリケーションがメッセージの最終的なあて先を決定する責任を持つのを防ぐために、そのミドルウェアは、メッセージを適切なあて先にメッセージを配送する Message Router (78) を含むべきである。

個々のメッセージルーティングパターンは、受信者から送信者を分離するのを助けてきた。 たとえば、Recipient List (249) は、すべての受信者に関する知識を、送信者から取り出し、ミドルウェアに入れることを助けることができる。 そういったロジックをミドルウェアレイヤーに異動することは、2つの意味で役に立つ。 一つ目は、多くの商用ミドルウェアとEAIスイートはそういった種類のタスクを実行するのに特化したツールやライブラリを提供している。 これは、Message Endpoint (95) (Event-Driven Consumers (498) のような関連するコード)を記述する必要が無いので、コーディングの仕事を単純化する。 また、ミドルウェアの中にロジックを実装することは、アプリケーションの中に実践的に実装するよりも、そのロジックを「よりスマート(smarter)」にできるようになる。 たとえば、動的な Recipient List (249) を使うことで、新しいシステムが統合ソリューションに追加されるときに、コードの変更を避けることが出来る。

しかしながら、多くの別々の Message Router (78) コンポーネントがあることは、我々が解決しようとした統合スパゲッティを管理するのとほとんど同じくらい難しくなりうる。


複数のあて先からメッセージを受信し、正しいあて先を決定し、正しいチャネルにメッセージを配信することが出来る中央 Message Broker を使いましょう。

そして、他のメッセージルーターを使って、Message Broker の中身を実装しましょう。


中央 Message Broker を使うことは、時々、上の図を説明するようなときに使用される名前としてのハブアンドスポークアーキテクチャスタイルを引き合いにだされる。

Message Broker パターンは、この章で説明された多くの他のパターンとは、少し違ったスコープを持っている。 個々のデザインパターンと違って、これはアーキテクチャパターンといえる。 それは、Pipes and Filters (70) アーキテクチャースタイルと比較できる。それは、より複雑なメッセージの流れと、コンポーネントとを一緒に結びつける基本的な方法を我々に与えてくれる。 個々のコンポーネントを単に結びつけるのに対し、Message Broker は、より大きなソリューションに関与し、そのシステムを管理するという不可避な複雑さに対処することを助ける。

Message Broker は一枚岩のコンポーネントではない。 内部的には、この章で説明してきた多くのメッセージルーティングパターンを使用します。 なので、一度 Message Broker を使用すると決めたら、Message Broker を実装するために、正しい Message Router (78) デザインパターンを選ぶことが出来ます。

Message Broker による中央保守管理の利点は、不利にも変わりうる。 すべてのメッセージが単一の Message Broker を通してやり取りされると、それは深刻なボトルネックになりうる。 いくつものテクニックで、この問題を緩和できる。 たとえば、 Message Broker パターンは、ルーティングを実行する単一のエンティティを開発しろと言ってるだけである。 開発時には、そのシステムに配置されるこのエンティティのインスタンスのがいくつなのかは規定していない。 もし、Message Broker がステートレスで設計されているならば(つまり、ステートレスなコンポーネントだけで構成されているならば)、スループットを改善するために、複数のブローカーインスタンスを簡単に配置することが出来る。 Point-to-Pointチャネル(103)の特性は、ひとつの Message Broker インスタンスのみが入力メッセージを消費する、ということを保障する。 また、リアルタイム性が必要な状況においては、究極的なソリューションは、結局、パターンの組み合わせになる。 同様に、多くの複雑な統合ソリューションにおいて、ソリューションの特定の部分を専門とする複数の Message Broker コンポーネントを設計することは理にかなう。 これは、保守不能になるとても複雑なすごい(uber) Message Broker を作ってしまうのを防ぐ。 逆に、もはや保守の単一点を持っておらず、Message Broker スパゲッティの型を作りうることは明確である。 Message Broker の組み合わせを使うひとつの優秀なアーキテクチャスタイルは、Message Broker 階層を作ることである。(図を参照) こういった構成は個々のサブネットからなるネットワーク構成と似ている。 もし、あるサブネット内の2つのアプリケーション間のみでメッセージが渡っていくなら、ローカル Message Broker がそのメッセージのルーティングを管理できる。 もし、メッセージが他のサブネットに向かうならば、ローカル Message Broker は中央 Message Broker にメッセージを渡すことができる。それは、すなわち、最終的なあて先を決定するということである。 中央 Message Broker は、ローカル Message Broker と同様な機能を実行するが、個々のアプリケーションを分離する代わりに、複数のアプリケーションからなるサブシステムを分離する。

すごい(Uber)ブローカを防ぐために、Message Broker 階層により分離する。

Message Broker の目的は、個々のアプリケーション間の結合を減少させるためなので、通常、アプリケーション間のメッセージデータフォーマットの変換を扱わなければならない。 もし、それが、メッセージを(恐らく隠された)相手先のメッセージフォーマットに変換しなければならないならば、メッセージのルーティングを抽象化する Message Broker があることは、送信アプリケーションを助けたりはしないだろう。 次の章では、この課題に着目するために、一連のメッセージ転送パターンを紹介する。 多くの場合において、Nの二乗問題を避けるために、Message Broker は、内部的に、Canonical Data Model (355) を使用する。(Nの二乗問題とは、システム内のすべての受信者間のひとつずつの変換機構が必要となるいくつものトランスレータが、受信者の二乗に比例して出来てしまうことである。)


例: 商用EAIツール

多くの商用EAIスイートは、統合ソリューションのために、Message Broker コンポーネントをうまく単純化するためのツールを提供している。 それらのツールスイートは、典型的には、Message Broker を開発と配備をサポートするいくつもの機能を提供している。

  1. 組み込み終端(endpoint)コード: 多くのEAIスイートは、メッセージバスとメッセージを送受信するためのコードを含んでいる。開発者は、転送に関するコードを書くことに煩わされることはない。
  2. ビジュアル設計ツール: それらのツールは、開発者が、ルーターや決定ポイントや変換などの、ビジュアルなコンポーネントを使用して、Message Broker の機能を構成することを可能とする。それらのツールは、メッセージの流れを直感的に見えるようにし、多くのそれらのコンポーネントから、評価関数やルールといった、ひとつのコードの集まりを記述するという苦労を削減する。
  3. 実行時サポート: 多くのEAIパッケージは、また、ソリューションを配備し、Message Broker を流れるトラフィックの監視するための、洗練された実行時サポートを提供する。


担当者のコメント

Message Broker という発想は理解できる。 しかし、Message Broker の階層構造が必要なほど巨大なシステムを単一の商用ミドルウェアで対応するのは無理があるように思う。 これは、あくまで概念の話だとすると、ビジュアルツールとかモニタリングのサポートとか言っても、結局、てんでばらばらになってしまうならば、その価値はだいぶ下がるなぁ。

みんなの突っ込み