Topics
Enterprise Architecture
Dmitri Maximovich、Eugene Kuleshov著
2006年1月30日
非同期のメッセージ処理は、多くのJ2EEアプリケーションにとって重要なユースケースです。このため、要求されたサービス品質(QoS)を、アプ リケーションが適切に扱えるように保証することが重要です。多くの場合、それには高価な分散(XA)トランザクションの使用が必要になります。しかし、こ の論文では、メッセージの取得にトランザクションを使用せずに、同じサービス品質を保証することが可能であることを提案します。さらに、我々のソリュー ションは、SpringのAOPフレームワークを使用して、メッセージ処理の様々なアスペクトを組織化します。
メッセージ駆動型Bean(Message-driven Bean:MDB)は、EJB 2.0仕様に導入されて以降、ほとんどすべてのエンタープライズJavaプロジェクトの基本になっています。MDBは、単純明快なAPIを持ち、ホームイ ンタフェースとローカル/リモートインタフェースを作成する必要がありません。このようなことから、MDBは、Java開発コミュニティに急速に普及しま した。ご承知のとおり、ほとんどの大規模J2EEプロジェクトの重要部分は、他のシステムとの統合に関連しています。異なるシステムを統合する方法として 望ましいのは、メッセージ指向ミドルウェア(MOM)が提供するエンタープライズキュー/トピックのインフラストラクチャを使用することです。それには、 すべてのJ2EEサーバが、JMS互換の独自のMOM実装を持つ必要があります。
エンタープライズJ2EEプロジェクトの大部分は、JMSメッセージの受信や送信に依存しています。このため、J2EEのアーキテクトや開発者が、 メッセージの生成や消費のための様々な方法に精通していることは極めて重要です。最終的には、それがプロジェクトの成否を左右することになるからです。最 近、SpringやActiveMQのメッセージ駆動POJOなど、MDBモデルに対する代替案が登場し始めました。これらは興味深い有用な技術です。し かし、現在のMDBモデルは確立されており、非常に簡単なので、J2EEコミュニティで広く採用されています。
この論文では、従来のMDBベースの消費モデルに焦点を当てます。ここでは、このようなシナリオを、よりパフォーマンスの高いトランザクションなし のメッセージ取得を使用するように改良する方法を示します。同時に、ビジネスケースが、once-and-only-onceの(ビジネスコードはメッ セージを1回しか処理しない、かつメッセージは失われない)サービス品質(QoS)を要求することを前提にします。これは、最も厳しいQoSで、これを実 現することは最大の関心事です。
ほとんどのJ2EEプロジェクトで、JMSメッセージを消費するユースケースが生じたときは、いつもMDBが使われると言って間違いありません。最 も些細なケースの他に、入力メッセージを失ったり、メッセージを重複処理することが許されるようなビジネスの場合、これらのMDBは、コンテナ管理トラン ザクション(CMT)区分のモデルに、
RequiresNewトランザクション属性を付けてデプロイされます。この設定が動作するためには、MDB がトランザクションありの
QueueConnectionFactory(または
TopicConnectionFactory)を使用する設定になっていなければなりません。このようなセットアップの場合、メッセージ消費処理は以下のステップで説明できます。
onMessage()メソッドに渡されます。
onMessage()呼び出しが戻ってきた場合、J2EEコンテ ナは、JTAトランザクションに加えられているすべてのリソースに対して、2フェーズコミットを実行します。JTAトランザクションに加えられているリ ソースの1つは、JMSメッセージの消費元なので、JTAトランザクションのコミットが成功したら、そのメッセージはキュー/トピックから削除されます。
onMessage()呼び出しが
RuntimeExceptionを 送出した場合、J2EEコンテナは、ステップ3でJMSメッセージを消費した消費元を表すXAResourceに対してロールバックを実行します。これに よって、このメッセージはキュー/トピックに留まり、後で再配信されることになります。また、この場合、MDBインスタンスは破棄され、処理プールから削 除されます。
このように、トランザクションありのメッセージ消費処理は非常に頑強です。このような処理モデルによって、once-and-only-onceの QoSが保証されます。つまり、メッセージが1度だけ正常に処理されるか、全く処理されないか(予め定義された再試行回数または生存時間を超えた後で キューから削除されるか、またはデッドメッセージキューに移される)のいずれかになります。
|
|