レベル: 中級 Jaliya N. Ekanayake (jaliya@opensource.lk), Software Engineer, Lanka Software Foundation
2005年 9月 07日 Apache Sandeshaと、そのアーキテクチャーの概要を学びましょう。Apache Sandeshaは、Apache Axisの上に構築された次世代SOAP(Simple Object Access Protocol)である、WS-ReliableMessagingプロトコルの実装であり、Webサービスへのサポートを大幅に拡張しています。ソフトウェア業界が、多くの異機種混合システムを結合してエンタープライズ・ソリューションを提供するSOA(Service-Oriented Architecture)に向かう中で、Webサービスは中心的な役割を果たします。そして、その接続性のベースとなるのは、システム間で交換されるメッセージです。堅牢なコミュニケーションを実現するには、ソフトウェア・コンポーネントのフェールやシステム・フェール、あるいはネットワークのフェールに際しても、分散されたアプリケーションの間でのメッセージ伝達は充分に信頼できるものでなければなりません。IBMとMicrosoft Corporation、BEA Systems, Inc.、そしてTIBCO Software, Inc.が公開したWS-ReliableMessagingプロトコルは、上記のような要件に対してトランスポートに独立なソリューションを提供するものであり、このプロトコルの実装には、様々なネットワーク技術を利用することができます。
プロトコルのモデル
WS-ReliableMessagingプロトコルは、エンドポイント・マネージャー(endpoint managers, EPM)の概念を利用した、信頼性の高いメッセージ伝達を実現するためのソリューションです。提案されたモデルでは、2つのEPM、つまりRMソース(Reliable Messaging Source)とRM宛先(RM Destination)を使って、信頼性の高いメッセージ伝達を行います。図1は、2つのEPMのやり取りを、非常に抽象的なレベルで表したものです。
図1. 信頼性の高いメッセージング・モデル
上記のモデルで分かる通り、RMソースとRM宛先は、アプリケーションのソース(Webサービス・クライアント)とアプリケーションの宛先(Webサービス)に対して透明なメッセージ・パスを提供する一方で、信頼性の高いメッセージ伝達を行います。
Sandeshaのアーキテクチャー
SandeshaはApache Axisの上に実装されており、そのアーキテクチャーは、主にAxisと、上記の図1に示したモデルに従っています。Sandeshaの仕様によると、RMソースがエンドポイント参照を持つことは、中核的な要求となっています。
「RMソースは、RM宛先エンドポイントを固有識別するエンドポイント参照を持つ『必要があります』。固有エンドポイントに向けられたメッセージ間の相関は、意味のあるものである『必要があります』」。(詳細に関しては、参考文献のセクションに挙げたWS-ReliableMessageの仕様を参照してください。)
Axisアーキテクチャーは、同期式のメッセージング・フレームワークです。そのためSandeshaは、単にAxisの機能を利用しただけでは非同期メッセージングの要求をサポートすることができません。つまりSandeshaのアーキテクチャーは、信頼性の高いメッセージ伝達を実現するための機能に加えて、非同期メッセージングのフレームワークも提供する必要があるのです。こうした両方の要求をサポートするために、Sandeshaでは、クライアント側とサーバー側が共にSenderとReceiverを別々に持つアーキテクチャーを導入しています。ある特定なEPMに関するSenderとReceiver間の接続性をサポートするために、Sandeshaのアーキテクチャーでは、デフォルトでメモリー内Queueを使います。こうしたアーキテクチャーを持っているため、Queueの代わりにデータベースをプラグインすることができ、これによって究極的にはパーシスタンスが実現できることになります。
最上位レベルのアーキテクチャーを、図2に示します。
図2. Sandeshaの上位レベル・アーキテクチャー
このアーキテクチャーは、同期、非同期、両方のメッセージング・シナリオを完全にサポートしています。非同期パターンを使用する場合には、WS-Addressingが、メッセージ間の相関情報を提供します。しかし双方向トランスポート(HTTPなど)を使用する場合には、リクエストに対するAckが、同じ接続を使って送られる可能性があります。これは図2の破線で示されています。従って両方の送信側は共に、こうした状況を適切に処理できる必要があります。
Apache Axisの上に構築されたSandeshaのアーキテクチャー
Axis特有なコンポーネントを図2に追加すると、Sandeshaのアーキテクチャーが、より詳細に分かります。図3は、Sandeshaのアーキテクチャーを完全に示したものです。
図3. Apache Axisの上に構築されたSandeshaのアーキテクチャー
図3はRMソースとRM宛先の中にあるコンポーネントを示しています。この図では、1つのRMエンドポイントに1つのAxisエンジンしかありませんが、SenderもReceiverも送信や受信の機能にAxisを利用しているため、完全にAxisベースのアーキテクチャーとなっています。図3に示した個々のコンポーネントの詳細は、下記の通りです。
Clientは、Webサービスを呼び出す(利用する)プログラムです。上位レベルのアーキテクチャーで見ると、これはアプリケーション・ソースです。Sandeshaは、Clientにある1つのRMソースを使って、幾つかのWebサービス(別のRM宛先にある場合もあります)を呼び出す機能を持っています。
SandeshaContextは、ユーザーがRM特有の様々なパラメーターを設定するためのAPIです。Axisの呼び出し機構は主にコールに基づいていますが、SandeshaContextを使うと、クライアント・コードからSandeshaあるいはAxis特有のコンポーネントに対して、追加的なパラメーターを渡すことができます。このClientを使用すると、Clientがデフォルト値をオーバーライドする必要がある場合に、WS-Addressingに対する値を設定することができます。さらに、SandeshaContextを使うと、RMソースに対して様々なランタイム・パラメーターを設定することができます。
Callコンポーネントは、Axisのコール機構です。これによって、クライアントは同期呼び出し(1つのトランスポート接続でClientをブロックする)ができるようになります。もしWebサービス・クライアントが、(やはり1つのトランスポート接続で)非ブロック型を必要とする場合には、ClientはCallではなくAsyncCallを使う必要があります。Sandeshaでは、Clientは、CallでもAsyncCallでも使用することができます。
Axisエンジンは、Apache Axisのエンジンです。これは基本的にSOAP(Simple Object Access Protocol)エンジンであり、クライアントやサーバー、ゲートウェイなどといったSOAPプロセッサーを構築するためのフレームワークです。
RMSenderは、Axisエンジンのクライアント側で信頼性の高いメッセージングを実現するためにユーザーが使用すべき、トランスポート送信側です。ただし、RMSenderはトランスポート層に直接書き込むことはなく、リクエストを「Queue」に挿入します。
Queueは、Sandeshaでのパーシスタンス層です。信頼性の高いメッセージングは、メモリー内Queueを使用することによって実現されます。しかしSandeshaには充実したストレージ・マネージャーAPIが用意されており、非常に単純な方法で、データベースに基づいてストレージを実装できます。(Sandeshaは現在、メモリー内Queueしかサポートしていません。)Queueは1つのコンポーネントとして動作しますが、着信メッセージ用と出力メッセージ用に、2つのキューを保持しています。さらにQueueのインターフェースは、2つのストレージ・マネージャー、つまりClientStorageManagerとServerStorageManagerに対して、スローができるようになっています。この2つのストレージ・マネージャーは、(図3には示されていませんが)RMソースとRM宛先がQueueを利用するために必要な機能を提供しています。
Senderは、リクエスト・メッセージを送信するためのスレッド・プールで実行しているスレッドです。Sandeshaでは、クライアント側にもサーバー側にも、同じSenderコンポーネントを使います。Senderは、ある特定なEPM(RMソースあるいはRM宛先)から出てくる全メッセージを送信するために使われます。
Senderが、双方向トランスポート・プロトコル(HTTPなど)を使ってリクエストを送信する場合、<wsrm:AcksTo>アドレスが匿名のURI(Uniform Resource Identifier)に設定されていると、受信側が同じ接続を使ってAckを送る可能性があります。(参考文献のセクションの、最初と3番目の資料を参照してください。)Sandeshaは、同じトランスポート接続で送られるAckは処理しますが、同じトランスポート接続で送られるアプリケーション・レスポンスはサポートしません。
Receiverは、クライアント側でのリスナーであり、Sandeshaの受信側として使われる、AxisのSimpleAxisServerです。Receiverの機能は、メッセージ自体の中に含まれている相関情報に従って、非同期SOAPメッセージを受け付けてQueueに挿入することです。Sandeshaでは、Receiver内のRM宛先の構成と同じ構成を使っているため、非同期レスポンスの処理には同じコンポーネントを使います。(Sandeshaアーキテクチャーでは、非同期レスポンスは着信リクエストとして処理されますが、レスポンスを使ってWebサービスを呼び出すことはありません。レスポンスは、それぞれの相関情報を持って「Queue」に挿入されるのです。)
RMProviderは、サーバー側のAxisエンジン内でSandeshaが使用するプロバイダーです。RMProviderは着信メッセージを識別し、要求されたメッセージをQueueの中に挿入します。またAckやTerminate Sequenceなど、信頼性の高いメッセージングに特有なメッセージを生成します。
RMInvokerは、Webサービス・リクエストを実際のサービスにディスパッチする、実行可能コンポーネントです。RMInvokerはまた、(もしサービス・レスポンスがある場合には)、サーバー側のQueueにサービス・レスポンスを挿入します。Sandeshaには、幾つかのRMInvokerスレッドを使ってWebサービス・リクエストをディスパッチする機能があります。そのためWebサービスが、同じサーバー上にデプロイされた他のWebサービスを、デッドロックに陥ることなく呼び出すことができます。
Serviceは、Webサービスそのものです。上位レベルのアーキテクチャーでは、アプリケーション宛先(Application Destination)と呼ばれます。
メッセージング・シナリオに関する完全な説明
Webサービスのクライアントは、様々な方法でWebサービスを利用することができますが、その利用を左右する要因には、IN-OUTやIN-ONLYなどサービス操作のMEP(Message Exchange Pattern)や、トランスポート接続、クライアント・アプリケーションに対してWebサービス・エンジンが提供するブロッキング型、非ブロッキング型のAPIなどがあります。Apache Sandeshaでは、信頼性の高いメッセージングを実現するためにAxisがWebサービス・クライアントに提供している、こうした呼び出しパターンをすべて利用することができます。下記のメッセージング・シナリオは、RMソースとRM宛先にある様々なコンポーネントを呼び出すためのシーケンスを説明しています。
RMソースでのSandeshaContextの初期化
Webサービスを呼び出す前には、クライアント・アプリケーションがSandeshaContextを初期化する必要があります。Sandeshaで提案されているモデルでは、SandeshaContextに必要なパラメーターを、ユーザーが最初に設定し、初期化することになっています。WS-ReliableMessagingの仕様によると、SandeshaContextの1つのインスタンスは、1つのシーケンスを表します。しかし、もしClientがSandeshaContextのインスタンスを数多く作成して数多くのシーケンスを作成した場合には、SandeshaContextはシーケンスの集合として動作します。図4は、SandeshaContextを初期化する場合の呼び出しシーケンスを説明しています。
図4. SandeshaContextの初期化
RMソースでの終了シーケンス
Clientがレスポンスを受信した場合、あるいは片方向メッセージの場合で制御ブロックを取得した場合、Sandeshaでは、ClientはSandeshaContextを使って、そのシーケンスを「終了」するようにRMソースに対して明示的に知らせる必要があります。そうするとRMソースはアクティブなシーケンスを全てチェックし、それらを1つ1つ終了しようとします。SandeshaContextが、ある特定なシーケンスを待つための最大待ち時間は、そのシーケンスの中にある「活動の無い」時間です。図5は、シーケンス終了のためのステップを示しています。
図5. 終了シーケンス
双方向の場合のサービス呼び出し(サービスにレスポンスがある場合)
このシナリオでは、Webサービス・クライアントが、WebサービスのIN-OUT操作を呼び出します。Sandeshaでは、このタイプのIN-OUT操作がサポートされているのは、リクエストの送信とレスポンスの受信に別々のトランスポート接続を使用する場合など、非同期の環境です。このシナリオでは、<wsrm:AcksTo>値が匿名URIに設定されており、<wsrm:Offer>は<wsrm:CreateSequence>ヘッダーの中で送信され、Webサービス・レスポンスのシーケンスが提供できるようになっている必要があります。
RMソース
図6は、クライアント側での、このシナリオの呼び出しシーケンスを示しています。
図6. RMソースでのサービスの呼び出し
-
図4に示すように、ClientがSandeshaContextを初期化します。
- ClientがCallを呼び出します(これが、ClientからAxisエンジンに対する呼び出しポントになります)。
- RMSenderが、信頼性の高いメッセージングに特有なものとして必要なメッセージ(Create Sequence、Terminate Sequenceなど)を作成し、リクエスト・メッセージと共にQueueの中に挿入します。そしてレスポンスが受信されるまで、Queueを監視します。
- Senderは(初期化ステップで、SandeshaContextによって既に開始されています)、送信すべきメッセージのQueueを(ClientStorageManagerによって)監視し、新しいメッセージを見つけると、宛先に送信します。Senderは、送信用として利用できるメッセージしか取得しません。この機構によって、Create Sequence操作が完了したらSenderがWebサービス・リクエストを送信すること、そしてメッセージが適切なタイミング設定で再送信されることを検証するのです。
- このシナリオでは、Senderは最初にCreate Sequenceリクエストを送信します。Create Sequenceのレスポンスは、RMソースが<wsa:ReplyTo>アドレスの内容に応じて、同じトランスポート接続、あるいは別のトランスポート接続を使って受信します。いずれの場合でも、Queueはレスポンス・メッセージによって更新されます。これによって、SenderはWebサービス・リクエスト・メッセージを送信することができます。ある特定なメッセージが(まだAckされておらず、またRM Policy Assertionsから見て非活動タイムアウトになっていない限り)送信用に用意されます。
- 全メッセージに対するAckが受信されると、QueueはSenderがTerminate Sequenceメッセージを送るのを許可します。
- Receiverはメッセージを受信するとそれを識別し、そのメッセージのアドレッシング・ヘッダーの中にある相関情報を使ってQueueを更新します。このシナリオでは、ReceiverがWebサービス・レスポンスを受信すると、その受信確認を知らせるためにRM宛先に送信すべきAckメッセージを作成し、それをQueueの中に挿入します。Senderは後でこれを拾い上げ、RM宛先に対して送信します。RM宛先はまた、すべてのレスポンスに対するAckを受信すると、このレスポンス・シーケンスに対してTerminate Sequenceメッセージを送信します。
- RMSenderは、Webサービス・レスポンスがQueueに用意できているのを見つけると、このレスポンスをクライアント・アプリケーションに返します。この場合、ClientがCallを使っているかAxisのAsyncCallを使っているかは、RMSenderの操作には影響しません。
- Clientがすべての呼び出しに対するレスポンスを取得すると、Sandeshaはクライアント・アプリケーションに対して、そのシーケンスを終了するように要求します。このフェーズでは、RMソースはストレージをクリーンアップし、アクティブなシーケンスが何もなければ、SenderとReceiverがClientに制御を戻すのを止めさせます。
サーバーEPM
メッセージを受信した時にRM宛先で実行されるステップを、図7に示します。Queueを初期化する場合には、その特定なRM宛先への最初のメッセージでしか、SenderとInvokerが起こらないことに注意してください。
図7. RM宛先でのサービス呼び出し
- RMProviderはメッセージを受信し、それがWebサービス・リクエストであれば、そのメッセージをQueueに挿入します。それがプロトコル特有のメッセージ(Create Sequence Requestや、 Acknowledgement RequestあるいはTerminate Sequenceなど)の場合は、必要なアクションを起こします。例えばそれがAckに対するリクエストであれば、Ackメッセージを返送するために、AckメッセージをQueueに挿入します。
- RMInvokerはWebサービス・リクエストを待つために、(ServerStorageManagerを使って)Queueを監視し、Webサービスを呼び出します。Queueは、ディスパッチ用のメッセージを正しい順序で保持することになっています。サービス・リクエストにレスポンスがある場合には、RMInvokerはこれをClientに返送するために、Queueに挿入します。もしこれが最初のレスポンス・メッセージの場合には、RMInvokerはCreate Sequence Requestメッセージも挿入します。(これが行われるのは、Clientから<wsrm:Offer>を使った最初のリクエストが来た時に、送信シーケンスが規定されていない場合のみです。参考文献のセクションにある最初の資料を参照してください。)RMInvokerはまた、そのシーケンスに対する最後のレスポンス・メッセージがQueueに挿入されると、Terminate Sequenceメッセージも挿入します。
- 送信側は、RMソースと同様、送るべきメッセージがないか、Queueを監視します。そして送信メッセージを識別すると、即座にRMソースに送信します。
もしクライアントがIN-ONLY 操作でWebサービスを呼び出した場合には、RMソースでもRM宛先でも、呼び出しのシーケンスは、このシーケンスのサブセットになります。これを上記の図7に示しています。RM宛先の中の送信部分からのレスポンスを取得するまで、RMソースには待ち時間はありません。
まとめと今後の作業
Sandeshaは、Apache Axisの上に構築されたWS-ReliableMessagingプロトコルを実装しています。これによってAxisコミュニティーは、Axisそのものだけではなく、このプロトコルをサポートするMicrosoft .NETなど他のWebサービス・プラットフォームにおいても、高い信頼性でWebサービスの呼び出しを行うことができます。現状でのSandeshaは、ソフトウェア・コンポーネントのフェールに関してパーシスタンスを提供していません。しかしこれは、メモリー内Queueの代わりに、SOAPメッセージ用のストレージとしてデータベースを使用することで実現できます。今後の開発の焦点となるのは、この領域と、現在まだ開発中である新バージョンのAxis、Apache Axis 2の上にSandeshaを構築することでしょう。
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  | Jaliyaは現在、インディアナ州Bloomingtonにあるインディアナ大学にて、コンピューター・サイエンスを学ぶ大学院生です。彼はスリランカのUniversity of Moratuwaにて学士号を取得しています。また、Lanka Software Foundationのメンバーであり、Apache SandeshaとApache Axis2のコミッターであり、PMC for Apache Sandeshaの代表でもあります。彼はソフトウェア技術者として2年間の経験があり、Virtusa CorporationとLanka Software Foundationで働いた経験があります。連絡先はjaliya@opensource.lkです。 |
記事の評価
|