2015年1月22日木曜日

Python SimpleXMLRPCServerでHTTP/1.1による永続接続

え?まだ1.1使ってるの?いやいやその前に今時XMLRPCなの?という本質的な疑問はとりあえず横に置いておいて。

XMLRPCを使ったプロトタイプをPythonで作る場合、Python付属のSimpleXMLRPCServerxmlrpclibを使うのが一番簡単な方法ではないかと思います。Pythonのドキュメントにもこれらのライブラリを使ったXMLRPCサーバーおよびクライアントの解説があります。

ドキュメントに書かれている内容に従ってサーバーを実装すると、HTTPバージョンとして1.0が使われます。もちろん、普通に動作するのですが、RPCの度にTCP (HTTP) 接続を確立するので効率が気になります。短時間に大量のRPCを発行する場合は特にそうです。HTTPバージョン1.1では一度確立したHTTP接続で何度でもコマンドのやりとりが出きるので、できればHTTPバージョン1.1を使いたいと思っていたのですが、軽く検索してみてもなかなかこれといった情報が見つからず、かといって自前でHTTPバージョン1.1対応するのも面倒で放置していました。

先日Pythonのドキュメントを見ていたら、BaseHTTPRequestHandlerprotocol_versionという変数があり、これをHTTP/1.1に設定することでBaseHTTPRequestHandlerを使っているSimpleHTTPServerなどがHTTPバージョン1.1対応になるという記述を公式ドキュメントに発見しました。対象ライブラリの説明だけでなく、きちんと親クラスの説明も読まないとダメですね。SimpleXMLRPCServerもPRCリクエストの処理にBaseHTTPRequestServer由来のSimpleXMLRPCRequestHandlerを使っているのでなんとかなりそうです。


from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler

class HTTP11SimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
    protocol_version = 'HTTP/1.1'

class RPCMethods(object):
    def add(self, a, b):
        return a + b

server = SimpleXMLRPCServer(('', 8000), requestHandler=
HTTP11SimpleXMLRPCRequestHandler)

server.register_instance(RPCMethods())
server.serve_forever()


これでめでたくXMLRPCサーバーがHTTPバージョン1.1で応答するようになりました。xmlrpclibを用いたクライアントの方は、どうやら標準でHTTPバージョン1.1を使うらしく、サーバー側を対応するだけで永続接続が使えるようになります。

検索してでてこないということは、誰も使っていない (あるいは当たり前すぎて質問もされない) ということかもしれませんが、将来の自分のためのメモとして残しておきます。


2015年1月13日火曜日

Force10にOpen Network Linuxをインストール (その2)

Open Network Linux (ONL) で配布されている公式バイナリは、現在のところパケット転送機能を提供していません。これは2014年5月に開催されたOpen Compute Engineering WorkshopでBig Switch NetworksのRob Sherwood氏の資料にも明記してあります (14ページ)。実際、ONLのバイナリをForce10にインストールしただけの状態では管理用のイーサネットポートのみしか見えていなかったのは前回の記事に書いた通りです。

ハードウェアレベルでパケット転送をするためのルール設定にはASICとの通信が必要になります。通常、ASICへのアクセス情報を入手するためにはNDAの締結が必要になるため、ハードウェアアクセス部分を切り離してオープンソース化されているようです。

Rob Sherwood氏の資料によれば、以下の3種類のパケット転送モジュールが (2014年5月時点での) 近日中にリリースされると書かれています。

  1. Indigo2ベースのオープンフローエージェント
  2. OF-DPAベースの転送エージェント
  3. おもちゃの転送エージェントOpen Route Cache (ORC)
このうち、ORCは最新のONL配布物に含まれており、基本的な機能しか使えないものの、ONL箱をルータとして使うことができます。OF-DPAに関しては、githubで資料と参照コードが公開されているものの、現時点では簡単に利用できるものではなさそうです。

ORC自体のソースコードは公開されているのですが、Force10が採用しているBroadcomのASICにアクセスするためのライブラリはバイナリ状態でのみ提供されています。ORCはそのライブラリを動的にリンクし、ASICの操作を実現しています。

以下の手順でORCを起動します。

root@onl-powerpc:~# orc --daemon

ifconfig (もしくは ip link) コマンドでインターフェースを確認してみると、orcXXという名前で52個のインターフェースが作成されていることが確認できます。インターフェースにアドレスを設定すれば、他の機器と通信できます。また、ip routeコマンドなどで経路を設定すればパケット転送もできます。ハードウェア転送されていることを確認するには、tcpdumpコマンドでインターフェースをモニターしてみるとよいでしょう。Linuxカーネルにパケットが上がってこないため、tcpdumpでは転送されたパケットを観測することができないはずです。

ORCはLayer 3のパケット転送を補助するもので、Layer 2の機能は利用できません。スイッチ機器では複数のポートをひとつのブリッジにまとめて利用することが多いと思いますが、ORCではブリッジ設定ができません。残念ながら実用的な処理をさせることは難しいでしょう。

ORCのソースコードを見てみると、どうやって経路制御プログラムとASICの間で情報をやりとりすればよいかがうっすらと見えてきます。ORCでは、カーネルの経路制御操作時に発行されるNETLINKメッセージを観測し、インターフェースのアドレス情報、転送に必要となるFIBの情報などを適宜ASICライブラリを経由してハードウェアに落とし込んでいます。ASICライブラリはORC専用のもので、汎用的なアクセスライブラリが提供されているわけではないため、同じASICライブラリを別の用途で再利用するのは困難だと思われます。やはり本格的なスイッチを作ろうと思ったら、専用のアクセスライブラリを自作する必要があるようです。

Open Network Linuxは、ダウンドードしてきてそのまま使うソフトウェアというよりは、スイッチベンダー、SDN、NFV開発ベンダーが独自の機能を持った高性能なパケット転送装置を自作するための部品として考えるのが良さそうです。運用部分に慣れ親しんだLinuxを使い、なおかつ必要に応じてハードウェアアクセラレーション機能を組み込める箱が必要な場合には魅力的な選択肢になりそうでうs。