ソフトウェア設計者の多くはサービス指向アーキテクチャー(SOA)の設計にXMLを利用していますが、SOA規格ではXMLの使用は必須でなく、またSOAでXMLを使用する方法についてのガイダンスも提供されていません。そのため、ソフトウェア開発コミュニティーでは、サービスのエンドポイントとメッセージ定義(スキーマ)を定義する最善の方法を見出そうと試行錯誤を重ねていますが、このようなアプローチのほとんどはパフォーマンスについても拡張性についても良い結果を出せていません。
たとえば、General Motors Corp.はSOAにおけるebXMLの発案者ですが、Universal Business Language (UBL)を使用した初期の設計で作成されたXMLメッセージは150,000バイトから10メガバイト以上もあります。2004年、パフォーマンス・テスト業者であるPushToTestは、当時のJava™アプリケーション・サーバー・テクノロジーは十分なスループットを実現しておらず、GMのWebサービス・パフォーマンス・ベンチマーク調査には拡張性とパフォーマンスの問題があったと判断しました。
その当時、XMLベースのWebサービス・テクノロジーはまだ相当新しいものであり、さまざまな問題がありました。それらは次世代のアプリケーション・サーバー・テクノロジーで解決されると期待していたのですが、問題の大半はまだ残っています。
2005年にPushToTestが実施した新しいSOAパフォーマンス調査(「参考文献」を参照)では、現在のJavaアプリケーション・サーバーで構築されたアプリケーションが複雑なXMLメッセージを処理する際に、そのパフォーマンスが実動レベルに達していないことが明らかになりました。筆者が検出した問題は、初期の調査で明らかになった問題と同じものでした。
- Simple Object Access Protocol (SOAP)バインディング(プロキシ)は効率が悪く時間がかかる。
- 応答を処理するにあたって、要求ごとに全く新しいリソース・セット(オブジェクト、CPU、ネットワーク帯域幅)が必要となり、キャッシング・パターンが存在しない。
- リレーショナル・データベース・テクノロジーを利用したXMLデータの格納は時間がかかり、拡張性がない。
これら3つの問題を理解するには、ソフトウェア開発者がJ2EEアプリケーション・サーバー・ツールを使ってXMLサービスをどのように構築し、展開しているかを考える必要があります。
図1. WSDL定義の図
XMLベースのWebサービスを構築する際にはさまざまなテクニックを利用できますが、ほとんどの開発者はWeb Services Description Language (WSDL)によるサービス定義から始めることを好むようです。Javaアプリケーション・サーバーには、WSDL定義を入力してプロキシ・クラスを生成するユーティリティーが備わっています。プロキシはSOAP要求を受け取ると、それを処理するためにJavaオブジェクトまたはEnterprise Java Bean (EJB)に渡します。SOAPバインディング(プロキシ)は、サーブレット・インタフェースを介して呼び出されるJavaクラスです。
図2. Javaメソッド呼び出しの図
図2は、Webサービスの利用者がサービスに対するSOAP要求を出すしくみを示しています。SOAPバインディングでは、SOAPメッセージの本文からXMLコンテンツをデシリアライズします。メッセージの本文には複雑なデータ型が含まれていることが多いため、デシリアライズは多くの処理を必要とする複雑な操作です。たとえば、複数の値を持つハッシュ・マップを利用者がサービスに送信した場合、SOAPバインディングではハッシュ・マップのコンテンツをデコードし、値ごとにJavaオブジェクトのインスタンスを生成しなければなりません。1つのハッシュ・マップには別のハッシュ・マップが含まれている場合もあるので、SOAPメッセージ・コンテンツのデコード処理は容易ではありません。Apache Axisデシリアライザーのソース・コードを見てみれば、このことが良くわかります。
SOAPバインディングではJavaのRequestオブジェクトのインスタンスが生成され、そこにはSOAPメッセージ本文のコンテンツが含まれています。SOAPバインディングはターゲット・クラスでターゲット・メソッドを呼び出し、Requestオブジェクトをパラメーターとして渡します。ターゲットのEJBまたはJavaオブジェクトは、この要求に対する応答の作成に必要な処理をすべて行います。SOAPバインディングはEJBまたはJavaオブジェクトからの戻り値をシリアライズしてSOAP応答メッセージを作成します。応答オブジェクトの値を、SOAP応答メッセージにシリアライズできる値にデコードする場合も同様の複雑さを伴います。
一般的なJavaアプリケーション・サーバーのユーティリティーで作成されたSOAPバインディングの調査では、以下の問題が明らかになりました。
- アプリケーション・サーバー・ユーティリティーによって生成されたSOAPバインディングは効率が悪い。たとえば筆者が調べたところ、明白な理由もなくSOAP要求のコピーを複数作成する(各要求はStringオブジェクトとしてインスタンス生成される)SOAPバインディングがいくつかありました。また、SOAPメッセージ本文に500の要素が含まれたSOAP要求をデシリアライズするために、最大15,000ものJavaオブジェクト・インスタンスを生成するSOAPバインディングもありました。
- CPU 3.0 GHz Intel Xeonデュアル・プロセッサーを搭載したサーバーで、10,000バイトのペイロードに50の要素が含まれた単純なSOAPメッセージを処理する場合のスループットは15から20 TPS(トランザクション数/秒)。筆者の調査では、SOAPメッセージの複雑さとサイズが増すにつれて、拡張性とパフォーマンスに大きな問題が発生しました。100,000バイトのペイロードに750の要素が含まれているSOAPメッセージの場合、スループットは1.5 TPSまで低下しました。SOAPメッセージ本文に含まれる要素数が多く各要素が深いほど、問題は深刻になります。
SOA設計ではパフォーマンスの問題が複雑になります。SOAはコンポーネント・ソフトウェアを再利用するための技術です。1 つのサービスからチェーン内の別のサービスを呼び出して、利用者からの要求に対する応答を決定することもよくあります。
図3. 利用者の図
上記のスタックでは、1つのサービスだけでパフォーマンスの問題が発生するだけではなく、各サービスで要求と応答のシリアライズとデシリアライズを行うため、サービスごとに同じオーバーヘッドが加わります。パフォーマンスの問題は、呼び出されるサービスのレイヤ数に応じて複雑になります。
SOAPバインディング・プロキシの低速問題のほかに、SOA設計では以下の2つの問題を無視あるいは見過ごしていることがあります。
まず、SOA設計では、中間層のサービス・キャッシングを使ってSOAのパフォーマンスを高める可能性を見過ごしている場合があります。たとえば、SOA設計におけるXMLスキーマの大半が応答の存続時間(TTL)値を定義するとします。この場合、SOAのサービス・パフォーマンスを高める有効かつ適切な方法は、サービス応答をキャッシュに入れ、サービスが次に同じ要求を受け取ったときに、キャッシュに入れた応答を再実行することです。
次に、筆者が実施したSOAパフォーマンス・テストでは、Streaming API for XML (StAX)、XMLバインディング・コンパイラー、Java Architecture for XML Binding (JAXB)、Document Object Model (DOM)の各技術を始めとして、さまざまなXMLメッセージ解析アプローチを試してみました。パフォーマンスの高いものもあり、たとえばStAXパーサーの多くはDOMパーサーよりも2倍から10倍も高いパフォーマンスを実現しました。
Javaオブジェクト以外を使ってSOAPバインディングを実現すれば、パフォーマンスは向上するのではないでしょうか。たとえば、送られてきたSOAP要求をネイティブXML環境で処理すると、JavaベースのSOAPバインディングは不要になり、Javaオブジェクトへのシリアライズによるパフォーマンス低下も避けられると思われます。
さらに、Java Virtual Machine環境を使いながらもJavaオブジェクトの構築を避けるネイティブXML環境もあります。たとえば、Raining DataのTigerLogic XDMSとKawa/Qexoでは、XQueryからJavaバイトコードに直接変換することで、XML処理コードを実装しています。これは、バイトコードとして実装されたXQueryを使うXML処理コードの方が、Javaオブジェクトを使うよりもスループットとコード行の点で効率的なためです。
FastSOAは、以下の問題に対処するアーキテクチャーおよびソフトウェア・コーディング・プラクティスです。
- FastSOAでは、Javaオブジェクトの必要性を減らし、ネイティブXML環境を使ったSOAPバインディングの実現を増やすことで、SOAPバインディング(プロキシ)のパフォーマンス問題を解決します。
- FastSOAでは、SOAサービスの高速化を実現するために中間層のサービス・キャッシュを採用しています。
- FastSOAでは、ネイティブXMLパーシスタンスを採用することで、XMLからの相対変換によるパフォーマンスの問題を回避しています。
次の図に、FastSOAアーキテクチャーを示します。
図4. FastSOAアーキテクチャーの図
FastSOAアーキテクチャーは既存のWebベース・インフラと連携し、サービス利用者の要求を受信する中間層のキャッシュとして導入されます。たとえば、利用者がサービスに対してSOAP要求を行うと、中間層のキャッシュによってSOAPバインディング(プロキシ)が実行されます。バインディングはXQueryを呼び出し、XQueryエンジンでXML要求文書を処理します。XQueryはキャッシュをチェックし、その要求が以前にも受信されているかどうかを確認します。要求が以前にも受信されていれば、FastSOAサービスはアップストリームを使ってサービス要求を出す必要がなく、キャッシュから応答を返すことができます。このプロセスでは、キャッシングによってSOAパフォーマンスが向上するため、SOAの高速化が実現されます。
FastSOAアプローチの利点は以下のとおりです。
- サービスのエンドポイントが標準ベースである。他のアプリケーションにとって、FastSOAの中間層キャッシュはサービスのように見えます。
- 既存のシステムやコードを置き換える必要がない。FastSOAの中間層キャッシュは、データ集約/軽減サービスとして既存のデータ・センターに組み込まれます。
- アップストリーム・サービスが一時的に利用できない場合、FastSOAアプローチを使うと、サービスがオフラインの間でもキャッシュに入ったデータを容易にブラウズできる。
- キャッシュから要求が処理されることで、利用者とサービス間の通信サポートに通常必要となる帯域幅の量が減る。
実用的な見地からFastSOAを理解するために、次の応用例について考えてみましょう。
General Motorsでは、ebXMLベースのパターンとプロトコルを使って自動車ディーラーが製造部門から部品を注文できるサービスを、SOAパターンで作成しました。このサービスは、Software Technology in Automotive Retailing (STAR)組織のXMLスキーマに準じています。STARはGMなどの大手自動車メーカーによる共同組織です。STARはBusiness Object Document (BOD)スキーマを作成および保守しており、特に在庫チェックに関する要求を定義しています。
CheckInventory要求は、要求側を検証し、在庫のレベルと状況をチェックします。サービス利用者は、STARスキーマに従って在庫要求文書を作成します。利用者はこの文書を要求に組み込み、ネットワークを介してサービスへ送信します。するとサービスにより、在庫のある部品を示す在庫状況応答が送信されます。
この部品注文サービスでは、FastSOAパターンを利用することでネットワーク帯域幅の必要性を減らし、冗長な要求への応答に使われるサービス帯域幅を軽減しています。
たとえば、自動車ディーラーからの部品に関する在庫応答には、存続時間(TTL)要素が含まれています。このTTL要素は、応答が有効状態である秒数を定義します。たとえば、GMでこの値を60秒に設定している場合、FastSOAはこの60秒の間に、中間層の格納済み在庫応答キャッシュから在庫要求に応答します。このサービスならば、不要な帯域幅が使われるのを防げるだけでなく、要求に対する応答時間も短縮されます。
次の表に、ネットワークにおけるサービスの高速化メトリクスの計算方法を示します。このネットワークでは、サービスはローカル・ネットワーク外のサーバーに常駐し、FastSOAのデータ軽減/集約サービスはローカル・ネットワークに常駐します。
| アクション | キャッシングなし² | キャッシング有効² |
|---|---|---|
| 最初の要求を処理する時間 | 1765¹ | 2218¹ |
| キャッシュに要求を格納する時間 | 0¹ | 453¹ |
| 2回目以降の同一要求または冗長要求 | 1765¹ | 320¹ |
| インターネットの所要帯域幅 | 30,400キロビット | 304キロビット |
| 所要時間合計 | 2941分 | 533分 |
¹記載されている時間はすべてミリ秒単位です(1秒 = 1,000ミリ秒)。 ²以下のことを前提としています。
|
FastSOAの実装では、XQueryによって部品注文サービスが実装されます。XQueryは在庫サービスに対して要求を出し、応答の内容を読み取り、在庫サービスに再度アクセスせずに以前に格納済みの応答を再実行できるかどうかをランタイムで判断します。
これにより、サービス環境でFastSOAのデータ軽減/集約アーキテクチャーが実装されます。XQueryとネイティブXMLデータベースを組み合わせると、以前の要求と後続の要求が同じで、データがまだ新しい状態の場合に、以前にキャッシュに格納された応答データを再実行するサービスが実現され、結果的にサービスが高速化されます。
FastSOAアーキテクチャーはJavaコードとリレーショナル・データベース・テクノロジーを使って実装できますが、Javaオブジェクトを使って作成されたサービス・バインディングをテストする場合や、リレーショナル・データベースを使ってXMLを永続化する場合は、パフォーマンスと拡張性に深刻な問題が発生します。このため、代わりにXQueryやXSLT、ネイティブXMLデータベース・テクノロジーを検討することをお勧めします。
筆者は、XQueryをアプリケーション開発用のネイティブXML環境として実装できる点に関心を持っています。初期のJavaテクノロジーと同様に、XQueryコミュニティーもXQueryを開発用プラットフォームとして確立および実証しようとするエネルギーに溢れています。確かに、XQueryの規格以上に拡張し、XQueryがSOAP要求を作成できるようにしているXQuery実装がほとんどです。たとえば、JDBC、SOAP、JMSの各プロトコルを介して、他のサービスやJ2EEオブジェクト、データ・ソースへの照会を行うXQueryもあります。さらに、実用性の高い市販のXQuery実装やオープンソースのXQuery実装もすでに10種類以上あります。
最後に、FastSOAは中間層のキャッシングにネイティブXMLデータベースを利用します。これは、SOAデータが一般にXML形式でエンコードされるという理由と、リレーショナル・データベースはXMLなど階層構造になっていないデータの永続化とインデックス付けが苦手であるという理由によるものです。XMLデータを格納するリレーショナル・データベースは通常、Binary Large Object (BLOB)フィールド型を使ってXMLを格納しますが、これは効率的でなく、高速検索のためのインデックス付けも容易ではありません。リレーショナル形式のアプローチは一般に、ストリーミング・データの操作にはあまり適していません。XMLメッセージがWebサービス・ベースのネットワークを介して送信される場合は、リレーショナル・データベースとは無関係のストリーム・ベースのアプローチを使って処理することが理想的です。
中間層のサービス・キャッシングを採用すると、ここで説明したSOAPバインディングのパフォーマンス以上の利点を多く得られます。利点には、中間層のスキーマ変換、サービスのバージョン管理、ポリシー・ルーティング、サービス品質(QOS)処理などが挙げられます。たとえば、FastSOAでは、中間層のXMLメッセージ・スキーマ変換を使って、互換性のない異なるメッセージ型を必要とするサービス間で互換性を得ることができます。
ここでは、SOAのパフォーマンスと拡張性の向上と、XQueryのサポートにより中間層にXMLパーシスタンスを組み込むSOA設計の利点について説明しました。FastSOA設計では、ネイティブXMLパーシスタンスとXQueryを組み合わせて使用するため、サービス呼び出しが受信されるごとに、以前の要求からのキャッシュ値で応答すべきか要求を通すべきかを中間層が判断します。このサービスではXQueryを使って、サービス要求のメタデータ記述への照会に基づいて、キャッシュが有効かどうかを判断します。
この記事の執筆にあたり、Darin MacBeath氏、William Martinez Pomares氏、Bob Albo氏に意見および提案をいただきましたことに深く感謝します。
学ぶために
- Frank Cohenによる、『FastSOA: The way to use XQuery and native XML databases to build scalable Service Oriented Architecture』(Morgan Kaufmann Publisher刊)を読んでください。2006年に刊行予定です。
- またFrank Cohenによる、『Java Testing and Design: From Unit Tests to Automated Web Tests』も見てください。
- Frank CohenによるdeveloperWorksの記事、「パフォーマンス・テスト用のSOAPベース・アプリケーション」(2001年11月)を読んで、皆さんのWebサービスが実働可能かどうか、調べてみてください。
- Frankの記事、「Discover SOAP encoding's impact on Web service performance」(developerWorks, 2003年3月)を読んで、SOAPエンコーディングに関する選択肢と、それぞれのパフォーマンスや信頼性面での利害得失を学んでください。
- Frankは彼の記事、「XQueryの神話と誤解を暴く」(developerWorks, 2005年7月)の中で、XQueryを取り巻く様々な誤解を詳細に解説し、そうした誤解を解いています。
- XQuery
- Simple Object Access Protocol (SOAP)
- Web Services Description Language (WSDL)
- Howard Katzが最近更新した記事、「XQuery入門」(developerWorks, 2006年1月)を読んでください。
- Streaming API for XML (StAX) について調べてください。
- Java Architecture for XML Binding (JAXB) について、さらに学んでください。
- Document Object Model (DOM) の基礎を学んでください。
- オープンソースのXQueryエンジンである、Kawa/Qexoについて学んでください。
- developerWorksのXMLゾーンやSOA and web servicesゾーンには、他にも豊富な資料が用意されています。
製品や技術を入手するために
- SOAのパフォーマンスやスケーラビリティーを評価するための方法論やテスト・プラットフォーム、結果分析手法などを提供する、the FastSOA Performance Kitについて調べてください。
- Raining Data's TigerLogic XDMSの無料評価版を入手してください。
- Apache Axisを詳しく調べてください。
議論するために
- XQueryNowは、XML環境で作業を行うソフトウェア開発者やアーキテクト、IT管理者のための、無料のオンライン・コミュニティーです。
Frank Cohenはソフトウェア起業家で、1975年以降、世界規模のパーソナル・コンピューターの普及に貢献してきました。彼は、ソフトウェア設計、テクノロジー・アーキテクチャー、グラフィック・アートなどのスキルを活かして新製品のアイデアを生み出し、それを市場性のある製品になるように業界をリードしてきました。彼の経歴は、マイクロコンピューター用オペレーティング・システムの作成から始まって、ビデオ・ゲームを1つの産業として確立する手助け、Norton Utilitiesフランチャイズの設立の援助、Appleの仕事がミドルウェアおよびインターネット・テクノロジーに展開する援助、最初のe-commerceビジネスの1つを確立する作業の援助などと続いています。最近では、Inclusion.net社の共同設立者兼チーフ・テクノロジー・オフィサーを務めています。この会社は、簡単で、迅速かつ効率的な、ビジネス・ユーザーのための共同作業用ワークプレースを構築しています。