2009年02月27日

WSGIServerを3行でマルチスレッド化する

はてなブックマークに登録

WSGIとは

PythonでWebアプリを作るときに必ず出てくる単語にWSGIがあります。 WSGIとは、Web Server Gateway Interface の略で、WebサーバーとPython製Webアプリを つなげる標準インタフェースです。

WSGIの上で動くようにアプリケーションを作ると、そのアプリケーションは修正無しに Apache+mod_wsgi, Apache+mod_python, fastcgi, scgi, cgi, 等の環境で動かせるように なります。

他にもミドルウェアという考え方があります。例えばOpenID認証機能をWebフレームワークの プラグインとして開発した場合では他のWebフレームワークでは利用できないのですが、 WSGIミドルウェアとして開発すればWebフレームワークを問わずに利用できるようになります。

標準ライブラリのwsgirefモジュール

Python2.5から、標準ライブラリにwsgirefモジュールが追加されました。その中にはWSGIサーバーも 入っているので、自分で書いたWSGIアプリを手軽に立ち上げたいときに重宝します。

次のコードは、簡単なWSGIサーバー+アプリの例です。

from wsgiref.simple_server import *

def myapp(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['hello']

server = make_server('0.0.0.0', 8000, myapp)
server.serve_forever()

WSGIServerのマルチスレッド化

上記のコードで立ち上がるWebサーバーは、シングルスレッド&シングルプロセスで動作しているので、 複数のクライアントからアクセスされた場合に問題があります。接続が遅かったり不安定だったりする クライアントが一つでも合った場合、その接続が完了するか切断するまで他の接続ができないので、 接続に失敗したり数十秒かかったりすることになります。

普通はWebアプリを公開する場合には標準ライブラリのWSGIServerではなくて別のサーバーを使う ものですが、お手軽な方法として3行追加と1行修正のみで、他のライブラリ無しに マルチスレッド化したりマルチプロセス化することが出来ます。 次のコードが上記のコードをマルチスレッド化したものになります。

from wsgiref.simple_server import *
from SocketServer import *
class ThreadingWsgiServer(ThreadingMixIn, WSGIServer):
    pass

def myapp(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['hello']

server = make_server('0.0.0.0', 8000, myapp, ThreadingWsgiServer)
server.serve_forever()

このコードについて簡単に説明します。 wsgiref.simple_server.make_server は第三引数でサーバークラスを指定することができて、 デフォルト値は wsgiref.simple_server.WSGIServer になっています。 WSGIServerの継承関係は次のようになっています。

SocketServer.BaseServer
  ↑
SocketServer.TCPServer
  ↑
BaseHTTPServer.HTTPServer
  ↑
wsgiref.simple_server.WSGIServer

SocketServerモジュールには、ThreadingMixIn, ForkingMixIn というクラスがあり、 SocketServer.BaseServer を継承したサーバークラスであれば簡単にマルチスレッド化 したりfork化したりできるようになっています。 WSGIServer も BaseServer を継承しているので、ThreadingMixIn/ForkingMixIn クラスを Mix-in してやるだけでマルチスレッド化やマルチプロセス化が可能です。

小さなテクニックですが、Webアプリが完成するまではサーバーの設定の問題とアプリの 問題が混ざらないようにしたいときとか、Webサーバーの設定ファイルを書くのに慣れてなくて 後回しにしたいときに重宝します。

ちなみに、 flup というライブラリには、 thread pool や prefork を使ったWSGIサーバーがあって十分実用になる速度が出るので、 標準ライブラリのサーバーだと遅いという時に利用できます。


@methane

klab_gijutsu2 at 17:40│Comments(0)TrackBack(0)Python 

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 
Blog内検索
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント
最新トラックバック
Archives