EIP / Routing Slip


EIP

Routing Slip (回覧)

一言要約

  • メッセージの処理後の転送先が固定で決まらない(設計時に決まらない)なら、転送先アドレスをメッセージにいれたらいいよ。

要約

  • このセクションのルーティングパターンは、ルールセットに基づいて、1つまたは複数の送り先にメッセージをルーティングする。しかし、場合によっては、単体ではなくコンポーネントのシーケンスを通してメッセージを届ける必要がある。

問題提起

  • 例えば、処理ステップと、ビジネスルールの検証のシーケンスを受ける必要のあるメッセージを処理する、パイプとフィルタアーキテクチャを使用すると仮定してみる。検証の性質が大きく変化し、外部システムに依存するかもしない(クレジットカードの検証)ので、別のフィルターとして、ステップの各タイプを実装する。各フィルタは、着信メッセージを検査し、メッセージにビジネスルール(群)を適用する。メッセージがルールで指定されている条件を満たさない場合は、例外チャネルにルーティングされる。フィルタ間のチャネルは、メッセージが満たすべき検証のシーケンスを決定する。
  • ここで、それぞれのメッセージに対する検証のセットは、メッセージの種類に依存していると仮定する。この要件のために、メッセージの種類に応じたフィルタの異なるシーケンスを介して、メッセージをルーティングできる設定を見つける必要がある。どのようにして、ステップのシーケンスが設計時に知られておらず、メッセージごとに異なる場合であっても、ある一連の処理を介して、メッセージをルーティングすることができるだろうか?

この問題に対するキーとなる要件は、次のように要約することができる。

  • 効率的なメッセージフロー - メッセージが、必要な手順のみを流れ、不要なコンポーネントを回避する必要がある。
  • リソースの効率的な使用 - ソリューションはチャネル、ルータ、およびその他のリソースを大量に使用することがあってはならない。
  • 柔軟性 - 変更が容易な独立したメッセージのルート。
  • 保守が簡単 - メッセージの新しいタイプをサポートする必要がある場合は、エラーを避けるために、単一ポイントの修正が好ましい。

5つの代替案

  • ここで3つの処理ステップがあり、メッセージの種類によって、それらをバイパスすることができるケースを使用して、2つの代替案の説明する。
  • 1つ目の方法(A:本書を参照)では、各コンポーネントに、検証するかどうかを決定するルーティングロジックとビジネスロジックをブレンドする。この場合、再利用が困難になり、メッセージの種類ごとにおとなる順番で処理をするようなことをサポートしない問題がある。
  • 2つ目の方法(B:本書を参照)では、関心の分離を改善し、ソリューションのコンポジット能力を高めるために、各コンポーネントの内部の"ゲーティング(Gating)"ロジックをコンテンツベースルータ(Content-Based Router)に交換する。各ステップが他のステップから独立しており、ルーティングの決定を各ステップでローカルに行うことができる場合には、非常にうまく動作する。しかし、、各メッセージは有効なコンポーネント数の2倍の割合のチャネルを介して伝送される。またルーティング ロジックは、特定の種類のメッセージに対して、どの検証が行われるのか分かりずらく、また多くのフィルター間で分散される。また、同様に、新しいメッセージタイプを導入すれば、すべてのルータそれぞれを更新する必要があり、Aの方法と同様に、メッセージが共通の順序で手順を実行することに結びつく制限がある。
  • 3つ目の方法(C:本書を参照)では、チェーンは、特定のタイプに関連する一連の検証を含み、メッセージタイプ(オプションCを参照)に基づいて、正しい検証チェーンへの着信メッセージをルーティングするために、コンテンツベースのルーターを使用する。目的の機能を実装するために、単一のルーティング手順を追加するのみであるので、これまでで最も効率的な方法となる。しかし、検証ルールの可能な組み合わせのハードワイヤを必要とする。 また、同じコンポーネントを複数のパスで使用するかもしれない。このアプローチは、私たちに、不必要な重複につながるようなコンポーネントの複数のインスタンスを実行することを要求する。メッセージタイプの大規模なセットでは、多数のコンポーネントインスタンスと維持しなければならない関連付けられたチャンネルのために、メンテナンスの悪夢につながる可能性がある。要約すると、この解決策は、保守性を犠牲にして非常に効率的になっている。
  • 4つ目の方法(D:本書を参照)として、ハード配線の検証手順のすべての可能な組み合わせを避けたいのであれば、各検証手順との間でコンテンツベースのルーターを挿入する必要がある。ルーターは、盲目的に、チェーン内の次の利用可能なステップへのルーティングするのではなく、直接次の必要な検証手順にメッセージを中継する。このオプションでは、効率性と柔軟性を提供する。しかし、中心的な目標を得るという目標を解決するわけではない。ルーティングロジックは、独立したルータの連続にまたがっているので、まだ潜在的に多数のルーターを維持する必要がある。
  • この最後の欠点を解決するために、すべてのルータを単一の 「スーパールータ(E:本書を参照)」に組み合わせることができる。各検証手順の後、メッセージは、次に実行される検証ステップを決定するであろうスーパールータに戻される。スーパールータは、どの手順まで既に処理を終えているのかを、覚えて実行するためのメカニズムを考案する必要がある。このため、スーパールータは、ステートフルであるか、各フィルタが、通過したした最後のフィルタの名前を伝えるために、メッセージにタグを添付しなければならないだろう。この結果、3つ目の方法のトラフィックの約2倍になる。

Routing Slip(回覧)

  • 処理ステップの順序を指定したRouting Slip(回覧)を各メッセージに添付する。特別なメッセージ・ルーターで、各コンポーネントをラップし、。Routing Slip(回覧)からリストを読み込んで、次のコンポーネントへメッセージをルーティングする。
  • このパターンは、部門内の循環のためにマガジンに取り付ける回覧とよく似ています。(訳注:回覧板的なものを言っているようです)唯一の違いは、回覧を使うほとんどの企業で、 雑誌を読んだ後に、読んでいないリスト上の任意の人にそれ手渡すことができる一方で、回覧はあらかじめ定義済みのコンポーネントの順番を持っている。
  • 回覧は、ハードワイヤードソリューション(C)の効率と'スーパールータ "アプローチ(E)の中央制御を兼ね備えている。完全なルーティング方式を先行を決定し、メッセージに添付するので、意思決定の中心ルータに戻る必要はない。
  • 提案されたソリューションでは、このルーティングのロジックは処理コンポーネント自体に組み込まれていることを前提としている。Aを振り返ってみると、各コンポーネントにいくつかのロジックをハードコードする必要がある点で似ているが、重要な違いとしてRouting Slip(回覧)で使用ルータは一般的なものであり、ルーティングロジックの変化に対して、変更する必要がない。
  • これは、各コンポーネントに組み込まルーティングロジックは、戻りのアドレスが、アドレスのリストから選択された、リターンアドレスに似ている。リターンアドレスと同様に、コンポーネントは、ルーティングロジックの一部をコンポーネントに組み込まれているにもかかわらず、それらの再利用性とコンポジットの能力を保持する。
  • さらに、ルーティングテーブルの計算は、今までの処理コンポーネントのいずれかの内部コードに手を加えることなく、中心的な場所で行うことができる。

Routing Slip(回覧)のデメリット

  • いつものように、全くのフリーランチはない。まず、メッセージのサイズが若干大きくなる。ほとんどの場合、これは取るに足らないはずだが、私たちは今、メッセージ内(手順が完了している)プロセスの状態を運んでいることを認識する必要がある。これは、他の副作用を引き起こす可能性がある。例えば、メッセージを紛失した場合、メッセージ・データだけでなく、プロセスデータ(すなわち、メッセージが次に行くつもりだったプロセス)が失われる。多くのケースでは、すべてのメッセージの状態を中心的な場所で維持することは、レポートまたはエラー・リカバリーを行うために役に立つかもしれない。
  • Routing Slip(回覧)先の別の制限は、それが進行中になるとメッセージのパスを変更することができないこと。メッセージ・パスは道に沿って処理ステップで生成された中間結果に依存しないことを意味する。多くの現実のビジネスでは、しかし、メッセージフローは、中間結果に基づいて、変更を行い処理する。例えば、(在庫システムによって報告された)注文された商品の可用性に応じて、別のパスで続行したいかもしれない。また、これは中央の実体は、メッセージが事前に受けなければならないすべてのステップを決定することができなければならないことを意味する。これは、コンテンツベースのルーターを使用しての懸念と同様のデザインのいくつかのもろさにつながる。

レガシー・アプリケーションとの回覧を実装。

  • Routing Slip(回覧)は、個々のコンポーネントをルータのロジックで増強する能力を持っていることを前提としている。レガシーアプリケーションやパッケージ・アプリケーションを扱っているならば、コンポーネント自体の機能に影響を与えることができない場合があり、むしろ、メッセージングを介してコンポーネントと通信する外部ルータを使用する必要がある。これは必然的にチャネルとコンポーネントの数を増加させる。
  • しかし、Routing Slip(回覧)はまだ効率、柔軟性、保守性の目標との間の最良のトレードオフを提供する。

一般的な使用方法。Routing Slip(回覧)は、次のようなシナリオに非常に便利

  • バイナリ検証手順の連続:メッセージに情報を追加しないことにより、もはやメッセージが進行中にルーティングを変更できないという制限は問題にならない。まだ中央のRouting Slip(回覧)を再設定することで、検証ステップの順番を変更する柔軟性を適用することができる。各コンポーネントは、エラーのためにシーケンスを中断するかの、次のステップにメッセージを渡すかの2者択一の選択を持っている。
  • 各ステップでは、ステートレス変換:例えば、使用している私たちは、ビジネスパートナーの様々な注文を受けると仮定すると、相手に応じて、メッセージが異なる変換手順が必要な場合がある。パートナーごとにRouting Slip(回覧)しておくと、私たちに中心的な場所で各パートナーの手順を再構成するための簡単な方法を提供する。
  • 各手順では、データを収集するが、全く意思決定を行うものではない:いくつかのケースでは、我々は他のデータへの参照識別子を含むメッセージを受信する。例えばDSL回線の注文を受ける場合は、メッセージは、申請者の唯一の自宅の電話番号が含まれる場合がある。しかし、このシナリオでは、決定が終了するまで延期されます。それで、Routing Slip(回覧)を使用できる。

Routing Slip(回覧)を使用した単純なルータを実装

  • コンテンツベースのルータの欠点の一つは、それが可能な各受信者およびその受信者に関連付けられているルーティングルールについての知識を取り入れる必要があることだった。疎結合の精神の下で、他の多くのコンポーネントについての知識を組み込んだ中心的なコンポーネントを持つことは望ましくないかもしれない。コンテンツベースのルーターの代替ソリューションは、メッセージフィルタの配列と組み合わせたパブリッシュ・サブスクライブチャンネルだった。このソリューションでは、各受信者が処理するメッセージを決定することができるが、重複したメッセージ処理の危険に苦しんでいた。(訳者:ここの部分よく理解できませんでした。本章ではそのようなこと書いていない気がします。多分以前の章での議論が出てる?)
  • 指定したメッセージを処理するかどうかを決定することを、個々の受信者に有効にするための別のオプションは、GoFで説明されるように責任のチェーンとして動作するRouting Slip(回覧)の修正バージョンを使用することだ。責任の連鎖は、リスト内の次のコンポーネントにメッセージまたはルートを受け入れることを、各コンポーネントにに許す。回覧は、すべての参加者の静的なリストだ。これは、依然として中心的なコンポーネントは、すべての可能な受信者の知識を持たなければならないことを意味する。ただし、コンポーネントは、どのメッセージがどのコンポーネントによって消費されるのかを知る必要はない。
  • (本文中の図を参照)
  • Routing Slip(回覧)を使用すると、重複したメッセージ処理のリスクを回避する。同様に、メッセージが任意のコンポーネントによって処理されていないかどうかを判断することは容易である。主なトレードオフは、より遅い処理と、ネットワークトラフィックの増加である。コンテンツベースのルーターは、システムの数に関係なく一つのメッセージを発行しているが、Routing Slip(回覧)のアプローチは、平均して、システムの数の1/2と等しいメッセージ数を発行します。 メッセージを受信する最初のシステムがメッセージを処理するの高い機会を持ち、そのような方法でシステムを配置することができれば、この数を減らすことができます。しかしそれでも、メッセージの数は、コンテンツベースのルータよりも高い。
  • 単純なシーケンシャルリストより多くの制御を必要とするか、または中間結果に基づいてメッセージの流れを変更する必要があるケースがある。分岐条件、フォークとジョインをサポートしているので、Process Managerは、これらの要件を満たすことができる。本質的には、Routing Sl;ip(回覧)は、動的にビジネス・プロセスが構成された特別なケースだ。
  • Routing Slip(回覧)の使用と、中央Process Managerの使用の間のトレードオフは慎重に検討すべきである。ダイナミックRouting Slipはハードワイヤードソリューションの効率とメンテナンスの中心点の利点を兼ね備えている。しかし、複雑さが大きくなるにつれて、ルーティング状態情報がテーマの賢人(誤訳かも: themes sages)に分散されているシステムの分析とデバッグはますます困難になることがある。また、判断、フォークと結合、構成ファイルなどの構成要素を含むように、プロセス定義のセマンティクスを開始するので、設定ファイルを理解し、維持するのが困難になることがある。
  • 我々は、ルーティングテーブル内に条件文を含め、次のルーティング位置を決定するための条件付きコマンドを解釈するために、各コンポーネント内のルーティングモジュールを補強できた。我々は、追加機能を備えたこのソリューションの単純さに、過度な負担をかけないように、注意深く検討する必要がる。 もしこのタイプの複雑さを要求するなら、それはRouting Slip(回覧)の実行時の効率を放棄し、はるかに強力なProcess Managerの使用を開始する良いアイデアかもしれません。

例:組立サービスとしてのRouting Slip(回覧)

  • サービス指向アーキテクチャを構築するとき、単一の論理関数は、多くの場合、複数の独立したステップで構成されている。この状況は、主に2つ理由のために発生すr。まず、パッケージ化されたアプリケーションは、内部APIに基づいた、きめ細かなインターフェイスを公開する傾向がある。統合ソリューションにこれらのパッケージを統合する場合、より抽象度の高いレベルで仕事をしたい。たとえば、"新しいアカウント"操作 は、課金システム内に複数の手順が必要な場合がある。新しい顧客を作成し、サービスプランを選択し、住所情報を設定し、信用データを確認する等。
  • 第二に、単一の論理的な機能が複数のシステムにに分散されるかもしれない。 統合ソリューションの残りの部分に影響を与えることなく、システム間の責任を再割り当てするための柔軟性を持っているので、他のシステムからこの事実を隠したい。簡単に1つの要求メッセージに対して複数の内部手順を実行するためにRouting Slip(回覧)を使用することができる。Routing Slip(回覧)は、同一チャネルから別の要求を実行するための柔軟性を提供する。Routing Slip(回覧では、個々のステップのシーケンスを実行するが、単一のステップのように外側に表示される(図を参照)。
  • (本文中の図を参照)
  • 1。意図した動作と必要なデータを指定した着信要求メッセージは、ルックアップ・コンポーネントに送信される。
  • 2。参照コンポーネントは、サービスディレクトリから目的の操作に関連付けられている必要な処理手順のリストを取得する。これは、メッセージヘッダにチャネル(各チャネルは1きめの細かい操作に相当します)のリストを追加する。参照コンポーネントは、完了メッセージが参照コンポーネントに返されるように、リストにリターンチャンネルを追加する。
  • 3。検索コンポーネントは、最初のアクティビティのためにチャネルにメッセージを発行する。
  • 4。各ルータはキューから要求を読み取り、サービス・プロバイダに渡します。実行後、ルータは活動を完了したものとしてマークし、ルーティングテーブルで指定された次のチャンネルにメッセージをルーティングする。
  • 5。検索コンポーネントはリターンチャンネルからメッセージを消費し、それをリクエスタに転送する。外側に、この全体のプロセスは単純な要求 - 応答メッセージ交換のように見える。

例:WS-Routing

  • 多くの場合、Webサービス要求は、複数の仲介者を経由してルーティングする必要がある。この目的のために、マイクロソフトでは、Webサービス・ルーティング・プロトコル(WS-Routingの)仕様を定義した。WS-Routingは、仲介者の一連の送信者から受信者へのメッセージをルーティングするためのSOAPベースのプロトコル。WS-Routingのセマンティクスは、Routing Slip(回覧)のものよりも豊かだが、Routing Slip(回覧)を簡単にWS-Routingで実装することができる。次の例では、仲介者BとCを介してノードからノードDにルーティングされるメッセージのSOAPヘッダーを示している。
	<SOAP-ENV:Envelope
	xmlns:SOAP-ENV="http://www.w3.org/2001/06/soap-envelope">
	<SOAP-ENV:Header>
	<wsrp:path xmlns:wsrp="http://schemas.xmlsoap.org/rp/">
	<wsrp:action>http://www.im.org/chat</wsrp:action>
	<wsrp:to>soap://D.com/some/endpoint</wsrp:to>
	<wsrp:fwd>
	<wsrp:via>soap://B.com</wsrp:via>
	<wsrp:via>soap://C.com</wsrp:via>
	</wsrp:fwd>
	<wsrp:from>soap://A.com/some/endpoint</wsrp:from>
	<wsrp:id>uuid:84b9f5d0-33fb-4a81-b02b-5b760641c1d6</wsrp:id>
	</wsrp:path>
	</SOAP-ENV:Header>
	<SOAP-ENV:Body>
	...
	</SOAP-ENV:Body>
	</SOAP-ENV:Envelope>
  • 関連パターン: Content-Based Router, Message Filter, Message Router, Pipes and Filters, Process Manager, Publish-Subscribe Channel, Return Address