EIP / Message History


Message History

一言要約

システムを通じてメッセージの流れを追跡するために、メッセージに通過した全コンポーネントのリストを添付する。

要約

メッセージベースのシステムの主な利点の一つは参加者間の疎結合であり、メッセージ送信者と受信者はそれぞれの身元について仮定は(ほとんど)しない。メッセージ受信者はメッセージチャネルからメッセージを取得しても、一般的にどのアプリケーションがチャネル上のメッセージを置いたかは気にしない。メッセージは自己完結で定義され、特定の送信者に関連付けられていない。これはメッセージベースのシステムのアーキテクチャ上の強みの一つである。

しかしながら、同じ特性はデバッグや依存性の解析を非常に難しくさせる。メッセージがどこに行くかが分からない場合、我々はどうやってメッセージ形式内の変更の影響を評価できるか?同様に、どのアプリケーションがメッセージを発行したかが分からないと、メッセージとともに問題を直すのは難しい。

疎結合されたシステム内のメッセージフローを効率的に分析またはデバッグするにはどうすればよいか?

Control Busは、メッセージを処理する各コンポーネントの状態を監視しているが、個々のメッセージが取るルートには関与しない。Control Busは、通過する各メッセージのユニークなメッセージ識別子を公開する各コンポーネントを変更できる。この情報はこの後一般的なデータベースであるMessage Storeに収集される。このアプローチは、別のデータストアを含むかなりの量のインフラが必要となる。また、コンポーネントがメッセージの履歴を調査する必要がある場合にも、中央データベースに対してクエリを実行するため、データベースのボトルネックがリスクとなる(超訳)。

システムを通じてメッセージの流れを追跡することは、それほど単純ではない。各メッセージに関連づけられた一意のメッセージIDを使うことが自然なように思う。しかしながら、あるコンポーネント(例: Message Router)はメッセージを処理して出力チャネルにpublishした時、結果メッセージはコンポーネントがconsumeしたメッセージとは関連づいてない新しいメッセージ識別子を受け取る。よって、受信メッセージから送信メッセージにコピーされ、2つのメッセージが後で関連づけられる新しいキーを特定する必要がある。これは、コンポーネントがconsumeする各メッセージに対して1つのメッセージを確実にpublishした場合上手く動作する。しかしながら、これは多くのコンポーネント(例: Recipient ListAggregatorProcess Manager)には当てはまらない。

代わりにメッセージをタグづけすることで各メッセージのパスを特定することで、メッセージ自身は走査されたコンポーネントリストを集めることができる。もしメッセージシステム内の各コンポーネントが一意な識別子を運ぶ場合、各コンポーネントはpublishする各メッセージにその識別子を追加できる。

よって、メッセージにMessage Historyを添付する。Message Historyはメッセージが発信してから通過する全アプリケーションのリストである。

MessageHistory.gif

Message Historyはメッセージが通過する全コンポーネントのリストを管理する。(発信者を含む)メッセージを処理する各コンポーネントはリストに1つのエントリを追加する。Message Historyはシステム固有の制御情報を含んでいるためメッセージヘッダの一部である必要がある。ヘッダにこの情報を保持することはアプリケーション固有のデータを含むメッセージボディから切り離す。

コンポーネントがpublishするメッセージは全て単一のメッセージの結果というわけではない。例えば、あるAggregatorは単一のメッセージをpublishし、そぞれが自身の履歴を持つ複数のメッセージから集めた情報を運ぶ。もしMessage Historyにこのシナリオを表現したい場合、2つの選択肢がある。もし完全な履歴を追跡したい場合、階層ツリー構造として格納されるようMessage Historyを拡張できる。ツリー構造の再帰的性質により単一の「ノード」配下に複数のメッセージ履歴を保存できる。代わりに、単純なリストを保持して1つの受信メッセージの履歴のみを保持することができる。これはある受信メッセージが他の補助メッセージより重要である場合にうまく動作する。

Message Historyは、一連のメッセージが特定のビジネス機能や処理を実行するために沢山のフィルタを通して流す場合に最も有用である。もしメッセージがとる経路を管理するのが重要な場合、Process Managerが便利である。Process Managerは各入力トリガメッセージ用に1つのプロセスインスタンスを作成する。様々なコンポーネントを通じてメッセージの流れは中央的に管理され、各メッセージに履歴とともにタグづけする必要性を軽減する。

履歴を持つメッセージを備えることは、イベントを伝搬するPublish-Subscribe Channelsを使った場合にも別の重要な利点をもたらす。Publish-Subscribe Channelsを介して複数のシステムにアドレス変更を伝搬するシステムを実装している、とする。各アドレス変更は全ての関係するシステムにブロードキャストされレコードを更新する。このアプローチは新しいシステムの追加に対してとても柔軟である。新しいシステムは既存メッセージングシステムを変更することなく自動的にブロードキャストメッセージを受け取る。カスタマーケアシステムはアプリケーションデータベース内のアドレスを格納するシステムの一つであると仮定する。データベースフィールドへの各変更は、変更する全てのシステムに通知するためにトリガーされるメッセージが表示される。publish-subscribeパラダイムの性質により、「アドレスが変更された」チャネルにsubscribeしている全てのシステムがイベントを受け取る。カスタマーケアシステム自体は、セルフサービスのWebサイトを通じてなど、他システムで行われた変更を受け取るために、このチャネルをsubscribeする必要がある。これは、カスタマーケアシステムはただpublishされたメッセージを受け取ることを意味する。この受信したメッセージはデータベース更新にて発生し、順番に他の「アドレス変更された」メッセージをトリガーする。「アドレス変更された」メッセージが無限ループになってしまうことがある。無限ループを避けるために、subscribeするアプリケーションは、メッセージが全く同じシステムから発信されているかを判断するためにMessage Historyを調べ、そうである場合に受信メッセージを無視することができる。

例:TIBCO ActiveEnterprise?

多くのEAI統合スイートはMessage Historyのサポートを含んでいる。例えば、全てのActiveEnterprise?メッセージのメッセージヘッダにはどのメッセージが通過した全コンポーネントのリストを管理する追跡フィールドを含んでいる。この文脈において、TIBCO ActiveEnterprise?のコンポーネントが送信メッセージにconsumeされたメッセージと同じメッセージIDを割り当てることに気をつけることが重要である。これは複数のコンポーネントを通じてメッセージを追跡するが、メッセージIDは複数の個々のメッセージが同じIDを共有するため、システム全体で一意なプロパティではないことを意味する。例えば、Recipient Listを実装する時、TIBCO ActiveEnterprise?はconsumeされたメッセージのIDを各送信メッセージに転送する。次に挙げる例は2つの統合マネージャプロセスであるOrderProcess?VerifyCustomerStub?を含む複数のコンポーネントを通過したメッセージのダンプである。

tw.training.customer.verify.response
{
    RVMSG_INT 2 ^pfmt^ 10
    RVMSG_INT 2 ^ver^ 30
    RVMSG_INT 2 ^pfmt^ 10
    RVMSG_INT 1 ^pfmt^ 10
    RVMSG_RVMSG 108 ^data^
    {
        RVMSG_STRING 23 ^class^ "VerifyCustomerResponse"
        RVMSG_INT 4 ^idx^ 1
        RVMSG_STRING 6 CUSTOMER_ID "12345"
        RVMSG_STRING 6 ORDER_ID "22222"
        RVMSG_INT 4 RESULT 0
   }
   RVMSG_RVMSG 150 ^tracking^
   {
       RVMSG_STRING 28 ^id^ "4OEaDEoiBIpcYk6qihzzwB5Uzzw"
       RVMSG_STRING 41 ^1^ "imed_debug_engine1-OrderProcess-Job-4300"
       RVMSG_STRING 47 ^2^ "imed_debug_engine1-VerifyCustomerStub-Job-4301"
       }
}

関連パターン: AggregatorControl Bus,、Message RouterMessage StoreProcess ManagerPublish-Subscribe ChannelRecipient List

担当者のつぶやき

みんなの突っ込み