JBoss Fuseを使い倒す その2:デザインパターン概要編

2015年7月16日(木)
佐藤 匡剛(さとう ただよし)

詳細化のパターン

ここからは、個々のルートパターンを詳細化したパターンです。EIPの書籍では、詳細化のパターンはだいたい次のように並べられています。まず、そのルートパターンにおける基本的/代表的なものから始まり、次第に応用的なパターンに進み、そして最後にそのルートパターンにアーキテクチャ的な展望を与えるパターンで締めくくる、といった順番です。

・メッセージチャネルのパターン システム間の通信手段をチャネルという形に概念化して扱うESBにおけるデータ通信(とくにメッセージングという非同期型通信)の特徴は、システム間の通信経路を「チャネル」という実体として扱う点にあります。通信経路を実体化することで、異なる通信スタイルのサポート(ポイントツーポイント、パブリッシュサブスクライブ)や、特定の経路に設計上の役割を持たせること(無効メッセージチャネル、配信不能チャネル)、サービスレベルの設定(配信保証)などが可能となります。

チャネルという用語は、Javaのメッセージング仕様であるJMSのキューまたはトピックに相当するものですが、他にも製品ベンダーによって様々な名前で呼ばれています。EIPではそれらをベンダーフリーに言い表す用語として、「チャネル」を採用しています。

パターン概要Camel組込
[table03-1]Point-to-Point Channel
ポイントツーポイント・チャネル
受信者が1つに限定された1対1のメッセージを送るために用いる(JMSにおけるキュー)
[table03-2]Publish-Subscribe Channel
パブリッシュサブスクライブ・チャネル
メッセージを不特定多数へブロードキャストするために用いる(JMSにおけるトピック)
[table03-3]Datatype Channel
データ型チャネル
メッセージの処理方法が分かるように、1つのチャネルを流れるメッセージのデータ型を統一する
[table03-4]Invalid Message Channel
無効メッセージチャネル
データの内容に問題があって処理できないメッセージが転送される
[table03-5]Dead Letter Channel
配信不能チャネル
何らかの理由で宛先へ配信不能なメッセージが転送される(いわゆるDLQ)
[table03-6]Guaranteed Delivery
配信保証
システム障害があっても確実にメッセージが配信されるように、メッセージの配信前後でメッセージを永続化する
[table03-7]Channel Adapter
チャネルアダプタ
システム間統合に対応していないレガシーアプリケーションと接続するためのアダプタ
[table03-8]Messaging Bridge
メッセージングブリッジ
複数のESB同士を接続するために、メッセージを複製する
[table03-9]Message Bus
メッセージバス
複数のアプリケーションを、疎結合な方法で協調動作させる最適なアーキテクチャ

まず、チャネルにはポイントツーポイントとパブリッシュサブスクライブの2種類があることを把握するのが、メッセージングを使いこなす上での第一ステップです。データ型チャネルやチャネルアダプタは、システム間統合ソリューションを設計する上での基本的なプラクティスと捉えればいいでしょう。

無効メッセージチャネル、配信不能チャネルの2パターンは、非同期型通信がベースのESBで例外処理を設計する上で必須の考え方です。同期型通信のRPCなどと違い、非同期型通信ではメッセージ処理中に例外が発生しても、それを即座に呼び出し側に返せません。そのため、まずリトライが可能であれば何度かリトライを繰り返し、その後に例外の種類に応じて特定のチャネルへメッセージを転送するのが、ESBにおける例外処理です。転送されたエラーメッセージの処理方法を決めるのは、システム間統合ソリューションの設計者の役割です。

メッセージングブリッジは、ESBを機能的にスケールアウトさせる場合や、既存のESB同士を相互運用したい場合に参考になるパターンです。

最後のメッセージバスは、チャネルの観点から見たシステム間統合ソリューションのあるべきアーキテクチャを示したものです。これがまさに、JBoss FuseなどのESBのアーキテクチャそのものであることに気付かれるでしょう。メッセージバスと、後のメッセージルーティングで登場するメッセージブローカを合わせると、ESBの見取り図のようなものが見えてきます。その意味で、EIPはESBが普及する以前に、ESBのあるべき姿を描いた書籍という読み方もできます。連載の第1回で、EIPが唯一生き残ったESBのデファクト・スタンダードであるという説明をしましたが、ある意味それは必然であることがここから伺えます。

メッセージ構築のパターン チャネルを通して通信するデータの単位を、ヘッダと本文からなるメッセージの形式で扱う

ここではメッセージそのものに焦点を当てて、その活用方法がパターンとして紹介されます。メッセージのヘッダを有効活用することで、メッセージングにまつわる様々な問題を解決できます。

パターン概要Camel組込
[table04-1]Command Message
命令メッセージ
アプリケーションの手続きを呼び出すため、命令をメッセージにして送信する
[table04-2]Document Message
文書メッセージ
アプリケーション間でデータを転送するため、文書をメッセージにして送信する
[table04-3]Event Message
イベントメッセージ
イベントを通知するため、イベントをメッセージにして送信する
[table04-4]Request-Reply
リクエストリプライ
手続呼び出しのようなリクエストとリプライのやり取りを実現するため、リクエストとリプライのメッセージをそれぞれ別々のチャネルで送信する
[table04-5]Return Address
返信用アドレス
メッセージへの返信先チャネルをリクエスト側が指定するには、メッセージのヘッダに返信用アドレスを指定する
[table04-6]Correlation Identifier
相関識別子
リクエストリプライにおいて、リクエストとリプライのメッセージ間の対応関係を識別するために、リプライメッセージにリクエストメッセージを一意に特定できる相関識別子を埋め込む
[table04-7]Message Sequence
メッセージ順序
データを複数のメッセージに分割し、それぞれに通し番号を付けて送信することで、メッセージングで大きなデータを送信できる
[table04-8]Message Expiration
メッセージ期限
メッセージのヘッダに有効期限を埋め込むことで、古く無効になったメッセージを判定できるようにする
Format Indicator
形式インジケータ
同一チャネル上で将来的にメッセージのデータ形式に変更が発生するような場合は、データの中にどの形式が使われているかを明示できるようにデータ設計をする

命令メッセージ、文書メッセージ、イベントメッセージは、あくまで設計上メッセージにどのような役割を与えるかであり、システム間統合ソリューションの実装時に、このように区分するわけではありません。リクエストリプライ型の通信をメッセージングで実現するには2つのチャネルが必要である、というのはメッセージングの基本です。JBoss Fuseでは、実際に2つのチャネルが使われていることを意識せずにリクエストリプライを実現できる仕組みが備わっています。

返信用アドレス、相関識別子、メッセージ順序、メッセージ期限、形式インジケータはそれぞれ、より詳細な要求をメッセージング上で実現しようとする際にヒントとなるパターンです。それ以外にも、メッセージヘッダを独自に活用することで、多種多様な要求に対応できるでしょう。

メッセージルーティングのパターン パイプ&フィルタにおいて複雑なメッセージ処理を実現するには、メッセージをルーティングするフィルタを導入する

パイプ&フィルタアーキテクチャの「フィルタ」に相当するメッセージルーティングは、システム間統合ソリューションにおける中心的なロジックとなる部分です。続くメッセージ変換も同様にフィルタに相当しますが、メッセージルーティングではメッセージそのものに変更を加えることなく、あくまでメッセージをどのように配送するかということが中心のテーマとなります。

パターン概要Camel組込
[table05-1]Content-Based Router
コンテンツベースルータ
内容(コンテンツ)に基づいて、メッセージを異なる宛先に振り分ける
[table05-2]Message Filter
メッセージフィルタ
メッセージを、一定の条件によってフィルタリングする
[table05-3]Dynamic Router
動的ルータ
実行時に外部から設定変更可能なルータによって、メッセージの宛先を動的に切り替える
[table05-4]Recipient List
受信者リスト
メッセージを複数の宛先に一斉に送信する。宛先のリストは動的に変更できる
[table05-5]Splitter
分配器
1つのメッセージを分割して、それぞれを異なる宛先に送信する
[table05-6]Aggregator
集約器
複数のメッセージを1つに集約する
[table05-7]Resequencer
再配列器
順不同で流れてくる一連のメッセージを、正しい順序に並べ替える
[table05-8]Composed Message Processor
組立式メッセージプロセッサ
分配器、コンテンツベースルータ、集約器を組み合わせることで、メッセージを分割して部分ごとに並列処理し、最後に再集約するという複雑なメッセージフローを実現する
Scatter-Gather
分散・回収
複数の宛先にメッセージを送信し、その結果をまとめて受信したい場合に、受信者リストまたはパブリッシュサブスクライブ・チャネルを用いてメッセージを一斉配信し、結果を集約器でまとめて受け取る
[table05-9]Routing Slip
回覧票
メッセージごとに処理ステップ(宛先)が変わるようなメッセージフローを実現するために、各メッセージに処理ステップの順番を示した回覧票を持たせ、それに基づいてプロセッサからプロセッサへメッセージをルーティングする
[table05-10]Process Manager
プロセスマネージャ
回覧票よりも複雑で汎用的なメッセージフローの管理が必要な場合は、中央集権的なプロセスマネージャを導入し、そこでフローを一元管理する
[table05-11]Message Broker
メッセージブローカ
エンドポイント同士を疎結合にし、ルーティングを中央集権的に管理するアーキテクチャを追究すると、ハブ&スポーク型のメッセージブローカ・アーキテクチャになる

コンテンツベースルータ、メッセージフィルタ、受信者リスト、分配器、集約器、再配列器の6つは、メッセージルーティングの基本ブロックとなるパターンです。ほとんどのルーティングに関する要求は、この6つの組み合わせで実現できるでしょう。メッセージフィルタは、メッセージのコンテンツを条件に照らして、そのメッセージを次の宛先に通すかまたは破棄する(nullチャネルに送る)特殊なコンテンツベースルータと見ることもできます。

動的ルータは、上記の基本パターンに比べて少し特異なパターンです。このパターンは、実行時に外部から設定変更可能なインタフェースを作って、動的にルーティングを制御できる可能性を示しています。動的ルータはルーティングを外部から制御できるという特徴から、最後に登場するシステム管理のパターンと関連が深く、一緒に用いられることの多いパターンです。

組立式メッセージプロセッサと分散・回収は、上記の基本パターンを組み合わせてより複雑なルーティングを実現した例です。2、3の基本ルーティングパターンを組み合わせるだけで、かなり複雑で興味深い働きをするルーティングを設計できることが分かります。

メッセージフローをさらに動的に、柔軟にカスタマイズできるようにしようと突き詰めていくと、回覧票やプロセスマネージャのような設計にたどり着きます。ここまで来ると、メッセージルーティングはワークフローエンジンやBPMエンジンに近づいていきます。

最後のメッセージブローカは、先ほどメッセージチャネルのパターンでメッセージバスと共に触れたように、ESBの見取り図とでも言えるようなアーキテクチャパターンです。ESBにおいては、各アプリケーションはESBとだけ通信すればよく、アプリケーション間は疎結合に保たれます。アプリケーション間の連携は、ESBの中のルーティングによって一元的に管理されます。

Camel独自のパターン

オリジナルのEIPのパターンに加えて、Camelにはコミュニティによって集められた新たなルーティングパターンも追加されています。

Throttler(調節弁)メッセージの流量に制限をかけて、特定のエンドポイントが過負荷で性能を落とさないようにしたり、外部サービスとのSLAを順守したりする
Sampling(サンプリング)サンプリングによる調整弁の一種。一定の間隔でメッセージを抽出することで、流量を調節する
Delayer(遅延器)メッセージの配送をわざと遅延させる
Load Balancer(ロードバランサ)様々なポリシーによるメッセージのロードバランシングを実現する
Multicast(マルチキャスト)受信者リストの一種。マルチキャストでは、宛先のリストは設計時に固定され、動的に変更できない
Loop(ループ)特定のルーティングを一定回数繰り返す
著者
佐藤 匡剛(さとう ただよし)
レッドハット株式会社

グローバルサポートサービス JBossシニアソフトウェアメンテナンスエンジニア
オブジェクト指向ソフトウェアアーキテクト、SOA/ESBコンサルタントなどを経験した後、レッドハットに入社。レッドハットでは、JBoss Fuse Service Works、JBoss SOA Platform、JBoss WS、RESTEasyなどのインテグレーションミドルウェア製品に関する技術サポート、バグ修正、上流オープンソースプロジェクト(SwitchYard、JBoss ESB、JBoss WS、Apache Camel、Apache CXF)への貢献を行っている。ドメイン駆動設計(DDD)をはじめとするオブジェクト指向方法論や、システム間統合技術を専門としているが、最近は関数型プログラミングにも興味があり、勉強している。毎朝、娘を幼稚園に送り届けるのが日課。その後、自宅に戻って在宅勤務(Work From Home)をしている。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています