Webサービス開発者が使用可能なメッセージング・テクノロジーは、いくつもあります。高いパフォーマンスを提供するものもあれば、使いやすく、人間の目で読みやすいコードを生成するものもあります。Python Web Servicesデベロッパー の今回の記事では、4つの異なるメッセージング・テクノロジーを読者に紹介し、それぞれのテクノロジーごとに簡単なベンチマーク・アプリケーションを書いていただきます。この作業を行なうと、それぞれのアプリケーションから、各テクノロジーを簡単に比較するための基本的な統計を得ることができます。このコラムで検討する4つのテクノロジーは、SOAP、CORBA、XML-RPC、および古き良き低レベル・ソケットです。
この記事では、3つの異なるメッセージを送信する、単純なクライアント/サーバー・アプリケーションのデモンストレーションを行ないます。最初のメッセージは、クライアントからサーバーに送信されるストリングの形式になっています。このメッセージから、タイミングおよびメッセージ・オーバーヘッドに関する情報を収集することができます。読者が作成する2番目のメッセージは、最初のメッセージの逆であり、読者はサーバーからストリングを受け取ります。最後に、読者はこのサーバーに整数を送信します。これにより、バイナリー・ベースのメッセージに関するタイミング情報、およびメッセージ・オーバーヘッドの情報を収集することができます。
この記事で提供する分析からは、あまり一般的な結論を導かないようにしてください。私たちが検討する4つのテクノロジーは、すべてメッセージ・ベースのクライアント/サーバー・アプリケーションに適していますが、それらの長所と短所は非常に異なります。読者に適したメッセージング・テクノロジーを選択するためには、メッセージ・オーバーヘッドを直接比較するだけでは不十分です。それぞれのテクノロジーをさらに詳しく調べることにより、重要な相違点のいくつかを明らかにして、開発者が採用するテクノロジーについて、より十全な選択ができるようしたいと考えています。
タイミング情報を収集するためには、Pythonで使用可能なtime.time() 関数呼び出しを使用してください。生成された統計データを検討するときには、time.time() の精度がプラットフォームに依存し、場合によっては1秒単位になる可能性があることに注意してください。
異なるテクノロジーを使用してアプリケーションを実行する時は、TCP接続を介して実際に送信される情報の量を調べるための標準的な方法が必要になります。そのためには、tcpdump というツールを使用します (下記の参考文献セクションにリンクを示してあります)。tcpdump のダウンロードおよびインストールのプロセスは、使用するOSによって異なりますので、ここでは触れません。このサイトの文書は適切なものであり、少なくとも、特定のTCP接続に送信されるメッセージを収集してメッセージ・オーバーヘッドのテストを行なうだけのために、tcpdump を使用して実際のサンプル・コードを実行する必要はないはずです。
これらのアプリケーションをテストするときに、tcpdump で以下のオプションを使用して、メッセージを一時ファイルに送ります。
tcpdump -i lo -ae -s 0 -w /tmp/packets.txt |
使用できるオプションはほかにもたくさんあります (例えば、ポートまたはホスト名を使用してフィルター操作を行なうこともできます) が、今回の単純な事例では、これだけで十分です。-i lo オプションは、tcpdump に対し、どのインターフェースをlistenするのか (この事例ではループバック装置) を指示します。a オプションを指定すると、アドレスを名前に変換することが試みられます。e オプションを指定すると、リンク・レベルのヘッダー情報が出力に含まれるようになります。s 0 はtcpdump に対し、各パケット本体内のすべてのデータが必要であることを指示します。(tcpdump にパケットごとに決まったバイト数だけを保管するように指示したい場合には、ここで、ゼロではなく希望するバイト数を指定してください)。最後のオプションは、tcpdump に対し、マシンによって検討されるすべてのパケットを、/tmp/packets.txt というファイルにコピーするように指示します。上記のコマンド・ラインはLinuxマシン向けのものであり、また、tcpdump を実行するにはルートまたは管理者権限が必要な場合があります。
テスト・スイートを実行する前に、読者のシステムでいくつかのサード・パーティー製パッケージを実行しておく必要があります。それぞれのパッケージについて簡単に説明します。すでにこれらがインストールされている場合には、以下のいくつかのセクションは飛ばして、先に進んでください。
この記事で使用するCORBA ORBは、omniORBというものです (参考文献 に示したリンク先からダウンロードすることができます)。この例では、omniORBバージョン3.04およびomniORBPyバージョン1.4を使用します。UNIX以外のプラットフォームおよびUNIXのいくつかのバージョンでは、バイナリーが用意されています。ソースからビルドする場合には、該当のREADMEファイルを参照してください。基本ステップは以下のとおりです。バイナリーからインストールする場合には、ステップ7および8に示すように、PYTHONPATH およびPATH 環境変数を更新する必要があります。
- ソース・コードをダウンロードしてuntarします。
-
omni/config/config.mk内でユーザーのプラットフォームに対するコメントを外します。 -
cd omni/src && make export - 同じサイトからomniORBPyをダウンロードします (参考文献を参照してください)。
- それを
omni/src/libディレクトリー内にuntarします。 -
cd omni/src/lib/omniORBPy && make export -
PYTHONPATH環境変数を更新して、$OMNI_HOME/lib/pythonおよび$OMNI_HOME/lib/i586_linux_2.0_glibc2.1を指定するようにします。 -
PATHを更新して$OMNI_HOME/bin/i586_linux_2.0_glibc2.1を指定するようにします。
omniORBをインストールした後で、この例のためのスタブ・ファイルとスケルトン・ファイルを生成する必要があります。ここから例をダウンロードして、展開してください。その後で、src/omni ディレクトリーに移動して次のコマンドを実行してください。
omniidl -bpython server.idl |
Pythonバージョン2.1以降を使用している場合、このセクションは飛ばしてかまいません。ただし、それよりも前のPythonを使用している場合、または最新のxmlrpclib を入手したい場合には、このパッケージをダウンロードしてください。参考文献にリンク先を示してあります。インストールは簡単です。ディレクトリーを作成して、Pythonパス上の位置にアーカイブ・ファイルをunzipしてください。新規ディレクトリーには必ず__init__.py を追加し、Pythonモジュールとしてインポートできるようにしてください。
[molson@penny python]$ mkdir XmlRpc [molson@penny python]$ cd XmlRpc/ [molson@penny XmlRpc]$ unzip ~/downloads/xmlrpc-0.9.8-990621.zip Archive: /home/molson/downloads/xmlrpc-0.9.8-990621.zip inflating: README inflating: xmlrpclib.py inflating: xmlrpcserver.py inflating: xmlrpc_handler.py [molson@penny XmlRpc]$ touch __init__.py [molson@penny XmlRpc]$ |
必要な最後のサード・パーティー・ライブラリーはSOAP実装です。ベンチマークのために、ZSIを使用します。最新バージョンへのリンクは参考文献を参照してください。ダウンロードした後で、展開してpython setup.py install を実行すると、ZSIを使用できるようになります。
システムの準備ができましたので、ベンチマーク・アプリケーションを使用してそれぞれのテクノロジーを順番にテストすることができます。
最初にPythonで直接書かれたソケットを見てみましょう。このソケットは、比較の基準として使用することができます。その理由は、(ユーザー自身が追加するものを除き) プロトコル・オーバーヘッドがないためです。このことは、ソケットを直接プログラミングする際の利点となります。欠点としては、次のような多くの重大な問題を考慮しなければならないことがあります。
- 開発および保守する必要のあるコードが多くなる。
- ネットワークで使用する場合にデータ保全性が確保できない (もっとも、TCP自体で提供されるもの以外のデータ保全性を提供するのはCORBAだけですが)。
- 低位のエラー条件 (つまり、誤ったメッセージ・プロトコル、接続の中断)。
それでは、アプリケーションに移りましょう。このアプリケーションで使用するすべてのサンプル・コードは、ここから入手することができます。アーカイブ・ファイルをダウンロードして展開すると、4つサブディレクトリーが作られます。最初に、python というサブディレクトリーを取り上げましょう。TCP通信用に独自のプロトコルを作成することの利点の1つは、追加のサード・パーティー・ライブラリーをインストールする必要がないことです。これにより、配布作業に伴う頭痛の種が大きく減ります。
例題の配布物では、python/server.py というファイルがサーバーになっていて、これを使用して直接出されるTCP要求を受け取ることになります。これは、Pythonとともに配布される標準SocketServer モジュールを基にしたものです。このコードの中で注意すべき点がいくつかあります。まず、エラー検査がまったく行なわれないことです。それぞれのメッセージ・タイプごとに (そしてまた、存在しないメッセージ・タイプごとに)、クライアントはサーバーから受信したすべてのバイトを入念に検査する必要があります。2番目の注意点は、ハンドラーが単一要求を処理するように設計されていることです。読者のソケット・サーバーが多数の整数をきわめて高速に送信しなければならない場合には、このことが不利に働きます。送信する整数ごとに新しい接続を確立することが必要になるためです。単一接続で複数の要求を処理するようにこのサーバーを作成することも可能ですが、その場合には、ある接続でいつlistenを停止するのかをサーバーに知らせるために、start およびstop メッセージの形で、サーバーに対する追加のメッセージ・タイプ・サポートを追加する必要があります。このサーバー・ファイルについて注意すべき最後の点は、どのような形式の接続タイムアウトも存在しないことです。このようなサーバーの構成方法では、悪意のあるクライアントがサーバーに接続し、極端に大きなストリングを送信することにより、そのサーバー全体を専有してしまうことが可能です。
サーバーを開始するためには、1つのウィンドウでserver.py スクリプトを実行し、2番目のウィンドウでtime-client.py というテスト・クライアントを実行してください。これにより、クライアント・スクリプトを実行した端末にタイミング情報が出力されます。クライアントが終了すると、Ctrl-Cを押してサーバーを停止させることができます。メッセージ・オーバーヘッドをテストするためには、tcpdump を使用します。これを3番目のウィンドウで実行し、(サーバーを実行させたまま)size-client.py スクリプトを実行してください。これら2つのスクリプトの結果を下記の表1に示してあります。
私たちが検討する2番目のテクノロジーであるSOAPは、このコラムの読者にとって最もなじみ深いものであるはずです。しかし、SOAPはこの種のテクノロジーとしては新しいもので、登場したのは2年ほど前のことにすぎません。これは (一般には) トランスポートのためにHTTPを使用し、HTTP本体として送信されるXMLベースのメッセージを作成します。SOAPメッセージに、HTTPおよびXMLからのオーバーヘッドがあることは、言うまでもありません。ただし、このおかげでメッセージが人間にとって読みやすくなるわけですから、これは必ずしも欠点と考えるべきではありません。
例題の配布物には、soap サブディレクトリーが含まれています。これには、server.py、time-client.py、およびsize-client.py ファイルが入っています。これらは、直接書かれたソケットのアプリケーションにおける相当するファイルと、まったく同じように実行されます。この結果も、表1 に示されているとおりです。
Common Object Request Broker Architecture (CORBA)
CORBAの優れている第1の点は、SOAP、CORBA、およびXML-RPCのうちで、CORBAが最も古く、分散プログラミングに関する、並行性、トランザクション、セキュリティー、および認証という、比較的困難な問題のいくつかに取り組んできたことです。SOAPはそれらの基礎の上に出発したものであり、XML-RPCでは、プログラマー (つまり読者) がこれらの問題を処理する必要があります。(実際には、CORBA自体がこれらの機能を備えているわけではありません。しかし、このプロトコルはこうした機能をサポートするように設計されていて、ほとんどのORBでは、これらの機能の一部またはすべてがCORBA Services仕様を介して実装されています。)CORBAが (SOAPやXML-RPCに比べて) 優れている第2の点は、メッセージ・フォーマットがバイナリーであることです (ただし、これはまた、ある意味で足かせにもなっています)。その利点として、CORBAメッセージは、SOAPやXML-RPCのメッセージよりもはるかにサイズが小さく、オーバーヘッドがはるかに少なくて済むようになります。欠点は、CORBAメッセージをデバッグする必要がある場合に、問題が生じることです。すなわち、GIOPサーバーしかCORBAメッセージを理解しないことです。
例題の配布物には、CORBA サブディレクトリーが含まれています。ここで、すでに示した例における相当するスクリプトと同じようにして、スクリプトを実行してください。結果は、下記の表1に示してあります。
最後に、XML-RPCプロトコルを調べてみましょう。私たちは多くの人々から、XML-RPCはSOAPが果たす役割のほとんどを果たすことができると聞かされました。しかし、私たちは、Unicodeサポートやデータの型付けの柔軟性など、いくつかの点でXML-RPCはSOAPに及ばないと考えます。XML-RPCはSOAPよりもだいぶ単純なプロトコルであり、使いやすくできていますが、SOAPが、CORBAですでに解決された問題の多く (並行性やトランザクションなど) を解決する方向に向かって努力しているのに対し、多くのXML-RPC開発者がSOAPを使った開発に鞍替えしているのに、XML-RPCは現状に満足しているように見えます。
例題の配布物には、xml-rpc サブディレクトリーが含まれています。これらの例は、前の例と同じように実行することができ、結果は次のセクションで示すとおりです。
4つのすべてのメッセージング・テクノロジーのテスト結果のデータを、表1 に要約してあります。
表1.ベンチマーク・アプリケーションの結果
| テクノロジー | 接続時間 | ストリングの送信 (21,000文字) | ストリングの受信 (22,000文字) | 5,000個の整数の送信 | クライアントLOC | サーバーLOC | 1,000文字を送信する場合の実際のメッセージ・サイズ | 100個の整数を送信する場合の実際のメッセージ・サイズ |
|---|---|---|---|---|---|---|---|---|
| 直接書かれたソケット | 0.002242 | 0.001377 | 0.001359 | 6.740674 | 57 | 25 | 2,279 | 85,863 |
| CORBA | 0.000734 | 0.004601 | 0.002188 | 1.523799 | 37 | 18 | 2,090 | 27,181 |
| XML-RPC | 0.007040 | 0.082755 | 0.050199 | 100.337219 | 29 | 17 | 4,026 | 324,989 |
| SOAP | 0.000610 | 0.294198 | 0.279341 | 1,324.296742 | 32 | 10 | 4,705 | 380,288 |
どうですか? 人間にとっての読みやすさを求めると、コストがかなり高く付きます。SOAPおよびXML-RPCのメッセージはバイナリーのCORBAメッセージの14倍 以上も大きくなっています。今日の世界では、ほとんどの企業がT1で接続され、多くの世帯が256 KbpsのDSLで接続されていますので、大きなメッセージを恐れることはありませんが、5,000個の整数をサーバーに送信するテストの結果から分かるように、SOAPおよびXML-RPCは同じマシンにおけるCORBAに比べて、それぞれ882倍および66倍長い時間を要しています。
最初に見たときに意外に思ったのは、CORBAサーバーのほうが直接書かれたソケット実装よりもメッセージが小さく、速度が速いということです。この理由は (前にも述べたように)、直接書かれたソケットでは、サーバーに対して要求を行なうたびに新規の接続を確立する必要があるからです。TCPを介してサーバーに接続するときには、接続を確立するためにいくつかのメッセージがやり取りされます。接続を要求するために、クライアントからサーバーに3つのメッセージが送信され、サーバーから3つの確認通知が送られます。これを5,000回行なうと、これらの小さなメッセージが積み重なります。CORBA (および現行のほとんどのHTTPサーバー) は、接続プールを使用してこれに対処しています。
このほかに、統計分析では容易に定量化することのできない考慮事項もあります。それぞれのメッセージング・テクノロジーは、関連する属性が異なっていて、得意分野と苦手分野があります。直接書かれたソケットを例にとってみましょう。一般に、直接書かれたソケットでは、通信コードの作成、デバッグ、および保守のほとんどの作業を、プログラマーが行なう必要があります。ただし、作成するアプリケーションがオーバーヘッドに対してきわめて敏感な場合、または (メッセージング・テクノロジー・ライブラリーを使用することにより) コミュニケーション層の実装をサード・パーティーの手にゆだねたくない場合には、カスタム・コミュニケーション層の作成および保守に必要な作業の量は、それほどの障害とは思われなくなります。
CORBAは、今回のコラムで調べたプロトコルの中では最速ですが、学習曲線が最も急で、またメモリーのフットプリントも最大になるものと思われます (もちろん、使用するCORBA実装によって異なります)。また、CORBA仕様のオープン・ソース実装はたくさんありますが、CosTransactions、CosSecurity、およびCosConcurrencyなどのようなCORBAの必須機能を実現するには、それらの機能を読者自身で実装するか、あるいは商用のCORBA実装を購入する必要があります。後者の方法を選択した場合、数千、数万、あるいは数十万円の費用が予想されます。
XML-RPCおよびSOAPは、ほぼ同じカテゴリーに属します。両方とも、メッセージ・オーバーヘッドの量がきわめて多く、パフォーマンスはCORBAに比べてかなり低くなっています。しかし、多くのアプリケーションでは、実際にはこれらの要素は問題になりません。帯域幅、プロセッサー、メモリー、およびディスク・スペースの価格が日を追って低下してきているので、パフォーマンスの低下を補うための機器追加に、50~100万円程度を支払うことは受け入れられ易くなってきています。これにより、商用ORBを購入するよりも少ない出費で、人間の目で読みやすいメッセージという利点を確保することができます。SOAPおよびXML-RPCについて注意すべき最後の事柄は、両者がプレーンXMLに基づいているということです。つまり、XMLはわずかのXSLT操作によってどのようにも変換することができるため、読者のアプリケーションでインバウンド/アウトバウンドのXMLベースのメッセージ構造をサポートする場合、将来そのテクノロジーがどこに向かったとしても、コミュニケーション・インフラストラクチャーをきわめて容易に別の形式に移行することができます。
このコラムの次回の記事では、Python 2.2で標準とされているXML-RPCライブラリーについて、さらに詳しく検討する予定です。簡単なクライアント/サーバー・アプリケーションを作成して、ライブラリーの使用方法を示し、XML-RPCのいくつかの機能をSOAPにおける類似機能と比較することにします。
- この記事のサンプル・コードは、.zipファイルまたは.tgzファイルの形式でダウンロードすることができます。
- Python Web Services Web の前回の記事を参照してください。
-
omniORBホーム・ページからomniORBをダウンロードしてください。
-
tcpdumpホーム・ページには、このツールに関する文書および情報があります。ダウンロードしてご利用ください。 -
xmlrpclibの最新バージョンをPythonware.org からダウンロードしてください。 - SourceForgeからZSIをダウンロードすることができます。
- Python Web Servicesデベロッパー ・シリーズのPython SOAPライブラリー 第2回 (developerWorks、2002年2月) では、ZSIについてある程度詳しく説明しています。
- Python.orgでは、すばらしいPythonソケット文書がいくつか提供されています。
Mike Olson氏は、企業向けの知識管理アプリケーションのためのXMLソリューションを専門とするソフトウェア・ベンダーおよびコンサルタント会社である、Fourthought Inc. のコンサルタントであり、共同設立者です。Fourthoughtは、XMLミドルウェア用のオープン・ソース・プラットフォームである4Suite を開発しています。Olson氏の連絡先はmike.olson@fourthought.com です。

Uche Ogbuji氏は、Fourthought, Inc. のコンサルタント兼共同設立者です。この会社は、企業のナレッジ・マネジメントのためのXMLソリューションを専門とするソフトウェア・ベンダー兼コンサルタント会社です。Fourthoughtでは、XML、RDF、およびナレッジ・マネジメント・アプリケーション用のオープン・ソース・プラットフォームである4Suiteを開発しています。Ogbuji氏は、ナイジェリア出身のコンピューター・エンジニア兼ライターで、現在は、米国コロラド州ボールダーに住み、そこで働いています。Ogbuji氏の連絡先はuche.ogbuji@fourthought.com です。