JBoss Fuseを使い倒す その2:デザインパターン概要編
メッセージ変換のパターン システム間のデータ形式の違いを吸収するために、メッセージを変換するフィルタを導入する
メッセージルーティングと並ぶ、システム間統合ソリューションにおける中心的なロジックが、メッセージの変換です。
パターン | 概要 | Camel組込 | |
---|---|---|---|
Envelope Wrapper エンベロープラッパー | 生のアプリケーションデータをESB上で扱うために、データにエンベロープを被せてメッセージ形式(ヘッダと本文が分かれている)にする | ||
Content Enricher コンテンツ付加器 | 他のシステムと通信するための情報が不足しているメッセージに、外部のデータソースからデータを取得して補完する。 | ○ | |
Content Filter コンテンツフィルタ | メッセージから不要なデータを取り除く | ○ | |
Claim Check 荷物預かり | コンテンツフィルタで削除できない重要だがサイズの大きいデータを、ESBで取り扱いたい場合は、いったんそのデータをデータストアに永続化し、メッセージにはそのキー(荷物預かり票)を持たせる。データが必要になったら、コンテンツ付加器を用いてデータを復元する | ○ | |
Normalizer 正規化器 | コンテンツベースルータとメッセージ変換を組み合わせ、様々な形式のメッセージを、意味を変えずに標準の形式に変換する。 | ○ | |
Canonical Data Model 標準データモデル | データ形式の標準化戦略についての考え方。メッセージ変換によって、システム間統合ソリューション内部では標準のデータモデルのみ流れるように設計することで、メッセージ変換の組み合わせ爆発を防ぐ |
あらゆるデータをESB上で扱う際に、エンベロープラッパーの考え方が重要です。組み込みでのサポートこそ謳われてないものの、Camelでは全ての入出力データは自動的にExchangeオブジェクトに被せられて扱われるため、標準でエンベロープラッパーに対応していると言えます。
メッセージ変換の基本はメッセージのデータを増やすか減らすかですが、それぞれがコンテンツ付加器とコンテンツフィルタに対応しています。コンテンツフィルタと、メッセージルーティングのパターンであるメッセージフィルタの違いは、前者はメッセージの中身の一部分をフィルタリングするのに対して、後者はメッセージそのものをフィルタリングするという点です。これがメッセージ変換とルーティングとの違いを端的に表しています。
メッセージ構築のメッセージ順序パターンと並び、荷物預かりはESB上で大きなサイズのデータを扱う際の設計のヒントになります。まさしく空港で飛行機に乗る前に大きな荷物を預けるイメージで、アイデアとして純粋に興味深いパターンでもあります。荷物預かりは大きなデータを扱う場合だけでなく、特定のエンドポイントにそのまま公開したくない情報がある際の、情報隠蔽の手段としても利用できます。
最後の標準データモデルは、メッセージ変換をアーキテクチャの中に取り入れて、どうやってデータモデルの標準化を行うかに関するパターンです。他のメッセージ変換パターンより少し高い視点の話題を扱っています。企業内でのデータモデルの標準化というのは誰もが夢見るテーマではありますが、実現がなかなか難しいのもまた事実です。ESBが標準データモデルの実現を多少容易にしてくれるのは間違いありませんが、他のアーキテクチャレベルのパターン、メッセージバスやメッセージブローカとは違い、ESBを導入しただけで必ずしも実現できるパターンではありません。
Camel独自のパターン
メッセージ変換については、Camelは以下のパターンを新たにEIPに追加しています。
Sort(ソート) | メッセージの本文をソートする |
---|---|
Validate(妥当性検証) | メッセージのヘッダおよび本文のデータを妥当性検証する |
メッセージエンドポイントのパターン ESBが外部システムと接続する部分を、エンドポイントという形で抽象化する
これまでは通信経路であるチャネル、データであるメッセージ、そしてそのメッセージの配送(ルーティング)や編集(変換)に焦点が当てられてきました。ここでは、ESBの最後の重要箇所である、チャネルを通して外部システムと接続する部分(エンドポイント)に焦点が当てられ、様々な設計上の検討事項がパターンとして議論されます。
エンドポイントは、メッセージのコンシューマとプロデューサのどちらも含んでいます。しかし、メッセージを送信する場合に比べ、受信する場合の方が様々な設計上の工夫が必要であるため、コンシューマに関するパターンの比重が多くなっています。
パターン | 概要 | Camel組込 | |
---|---|---|---|
Messaging Gateway メッセージングゲートウェイ | アプリケーション側でESBとの通信層を設計する場合は、メッセージングのAPIをゲートウェイにカプセル化し、アプリケーションロジックとメッセージングのロジックを切り分ける | ○ | |
Messaging Mapper メッセージングマッパー | アプリケーションのドメインモデルとメッセージング層を完全に分離するには、DBアクセスにおけるORマッピングのような仕組みをメッセージングに導入する | ○ | |
Transactional Client トランザクションクライアント | ESBではクライアント側(メッセージ送信者または受信者)がトランザクション管理を主導する | ○ | |
Polling Consumer ポーリングコンシューマ | メッセージの受信方法の一種。一定間隔で明示的にポーリングして、メッセージの到着を確認する | ○ | |
Event-Driven Consumer イベント駆動コンシューマ | メッセージの受信方法の一種。リスナーを登録して、メッセージが到着したら自動的に処理が実行される。 | ○ | |
Competing Consumers 競合型コンシューマ | 1つのチャネルに対して競合する複数のコンシューマを走らせることで、メッセージを並列処理する | ○ | |
Message Dispatcher メッセージディスパッチャ | 競合型コンシューマと対照的に、メッセージ並列処理を調整するディスパッチャにまずメッセージを受信させ、ディスパッチャが適切なルールに基づき処理を後続の並列メッセージ処理プロセスに振り分ける | ○ | |
Selective Consumer 選択型コンシューマ | 一定の条件で選択的にメッセージを受信したい場合は、チャネル側のフィルタリング機能を使うか、メッセージ受信後にメッセージフィルタを用いて必要なメッセージだけを残すか、2通りの方法がある | ○ | |
Durable Subscriber 永続的サブスクライバ | サブスクライバがオフラインのときにチャネルに到着したメッセージも取りこぼしたくない場合は、永続的サブスクライバの設定を有効にする | ○ | |
Idempotent Receiver 冪(べき)等レシーバ | 同一メッセージの重複受信に対応するには、重複を検知して明示的に排除する仕組みを作るか、同一メッセージを複数回処理しても問題が起こらないようにシステムを設計する | ○ | |
Service Activator サービスアクティベータ | リモート手続呼出型のサービスにメッセージングのAPIを付加したい場合は、リクエストリプライ型のメッセージングをリモート手続呼出に変換する層(サービスアクティベータ)を導入する | ○ |
メッセージングゲートウェイとメッセージングマッパーは、エンタープライズアプリケーションアーキテクチャパターンにおけるゲートウェイ(Gateway)やデータマッパー(Data Mapper)のパターンにそれぞれ対応するもので、アプリケーションにメッセージングによる通信層を設計する際のベストプラクティスです。
ポーリングコンシューマ、イベント駆動コンシューマ、競合型コンシューマ、メッセージディスパッチャ、選択型コンシューマ、永続的サブスクライバ、冪等レシーバは、いずれもメッセージのコンシューマに関するパターンです。
ESBにおいては、エンドポイントの種類によってポーリングコンシューマとイベント駆動コンシューマのどちらを採用すべきか決まります。例えばデータベースのようにイベント駆動型のAPIを提供しないエンドポイントでは、ポーリングコンシューマが選択肢になります。逆にJMSやMDB(Message-Driven Bean)では、イベント駆動コンシューマを採用するのが自然でしょう。
競合型コンシューマとメッセージディスパッチャの2つは、ESBのクラスタリング環境を設計する際のヒントとなるパターンです。永続的サブスクライバと冪等レシーバは、ESBの耐障害性や重複排除といった要求を実現する上で必須の仕組みです。
システム管理のパターン
エンタープライズシステムは単に開発すれば終わりではなく、本番運用においてトラブルを検知・回避・復旧できるように、稼働状況を継続的に監視・管理する仕組みを構築するところまでがセットです。それは、ESBにおいても同様です。
システム間の統合を行うESBは、通常のアプリケーションとは異なる特徴を持ちますので、その運用・監視のアプローチにも独自のノウハウがあります。ここでは、そうしたESBに固有の運用・監視パターンがまとめられます。
パターン | 概要 | Camel組込 | |
---|---|---|---|
Control Bus 制御バス | ESBを監視・管理する仕組みを作るには、それ自身をESB上のシステム間統合ソリューションとして構築するのが有効である。ただし、監視・管理用のメッセージチャネルは本体とは別に用意する | ○ | |
Detour 迂回路 | コンテンツベースルータを制御バスによって制御することで、システム管理目的でメッセージフローを一時的に迂回させるような仕組みを実現できる。例えば、あるルートのメッセージを一時的に検証、テスト、デバッグするなどの用途に使う | ○ | |
Wire Tap 盗聴器 | ESBを流れるメッセージを途中で監視したい場合は、本来の宛先と監視用の宛先の2つを持つ受信者リストを導入して、本来のメッセージフローを邪魔せずにメッセージを監視する | ○ | |
Message History メッセージ履歴 | メッセージのルーティング履歴をメッセージ自身に記録していくことで、メッセージフローのデバッグや分析に活用できる | ○ | |
Message Store メッセージストア | ESB上のシステム間統合ソリューションに対して何らかのレポートを作成したい場合に、レポーティング用のチャネルを用意して、システム中の様々な場所を流れるメッセージを一箇所に記録する。 | ||
Smart Proxy スマートプロキシ | 返信用アドレスを使って返信先を指定しているリクエストリプライメッセージングの間にプロキシを挟みたい場合、プロキシ側でいったんメッセージの返信用アドレスをプロキシ自身に書き換える。プロキシに戻ってきたリプライメッセージは、ルータを使って元の返信用アドレスに送り返す | ||
Test Message テストメッセージ | ESBの健康状態を監視するために、本番稼働中のシステムに定期的にテストメッセージを流して内部動作を点検する | ||
Channel Purger チャネル消去器 | テストや本番稼働中において、チャネルに残ったゴミメッセージが動作に影響を及ぼさないように、チャネルのメッセージを一掃する仕組み |
システム間統合ソリューションで何より特徴的なのは、そのシステム管理もメッセージングをベースに構築するのが有効だという点です。それを端的に表したのが制御バスパターンです。EIPにおけるシステム管理の考え方は、この制御バスが出発点になります。
迂回路、盗聴器、スマートプロキシは、ルーティングの中にシステム管理用の部品を埋め込むアイデアを示したものです。特に盗聴器は非常にポピュラーなパターンで、Camelを使ったシステムでもよく使われます。
メッセージ履歴とメッセージストアは、システム間統合ソリューションの動作を分析・レポーティングするのに有効です。メッセージストアは、自分でその仕組みを構築しなければいけませんが、メッセージ履歴はCamelでは標準でサポートされており、何もしないでもすぐに利用できます。
最後に、メッセージングに固有のテストやデバッギングのノウハウ、テストメッセージとチャネル消去器も把握しておく必要があります。システム同士を統合するシステム間統合ソリューションでは、当然ながら単体テストよりも統合テスト以降がもっとも重要なテストフェーズになります。
特にテストメッセージが示すように、開発時だけでなく本番稼動時にも定期的にテストメッセージを流してシステムの健康状態を確認する、いわゆるアクティブモニタリングと呼ばれる手法がシステム間統合ソリューションでは非常に有効です。DevOpsが注目を集めている昨今、改めて本番環境にテストを組み込むというアプローチが見直されてもよいのかもしれません。
Camel独自のパターン
Camelは以下のパターンをシステム管理のパターンに追加しています。
Log(ログ) | メッセージをロギングする |
---|
おわりに
非常に駆け足でしたが、EIPの全体像を紹介しました。本記事は、あくまでEIPを実際のシステム間統合に適用するきっかけを作るための、最初の手引きに過ぎません。パターンの真の価値は、単に頻出する問題とその解決策がセットになっていることだけではなく、解決策に付随する様々なトレードオフや選択肢、設計上の検討事項などがエキスパートの手によって文書化されていることにあります。本記事で興味を引くパターンを見つけたら、ぜひ書籍を手にとってその詳細な議論にも触れてください。
次回はEIPをいくつかピックアップして、JBoss Fuse上で実際にどのようにパターンを適用できるかを紹介したいと思います。