Python simple_server tuning
GAE/PythonでごそごそやってますがたまーにGAEじゃ出来ない事をしたくなるときが有ります。ローカルのデバイス操作したりファイルごにょごにょしたり。そんな時は…Apache入れてmod_wsgi入れて…って言うのが王道にも思いますが結構大変。いっそのことdev_appserverで逃げようかとか思ったりもするもののライセンスも良く解からん上、シングルスレッド動作のwebサーバなので気が引けます。
で、Pythonに漏れなく付いてくるwsgiref.simple_serverとbottle+sqlalchemy/sqlite+flaskで落ち着いてたんですがやっぱりパフォーマンスが…。って事でちょっとぐぐる先生に聞いてみるとこんなページを紹介されるのでした。
Nicholas Piël » Benchmark of Python Web Servers
すげー、その調査力に感服。って違うry
gevent/libeventが良いですね~。wsgiref.simple_serverだと 2.6TPS エラー有りまくりだったアプリを試しにgevent.wsgi.WSGIServerにするとそれだけで13.7TPS!エラーも無しといい感じ。なんですが個人的なホーム鯖でgevent/libeventは流石にやり杉な雰囲気です。お試しはLinuxでやってますが諸事情からホーム鯖はWindowsです(ドライバがWindowsしかない…)。Internet公開もしないしってことでもうちょっとwsgiref.simple_serverで頑張ってみることにします。
そもそもシングルスレッドを何とかします。
from SocketServer import ThreadingMixIn
class ThreadingWsgiServer(ThreadingMixIn, WSGIServer):
passclass ThreadingWSGIRefServer(ServerAdapter):
def run(self, handler): # pragma: no cover
from wsgiref.simple_server import make_server, WSGIRequestHandler
if self.quiet:
class QuietHandler(WSGIRequestHandler):
def log_request(*args, **kw): pass
self.options['handler_class'] = QuietHandler
self.options['server_class'] = ThreadingWsgiServer
srv = make_server(self.host, self.port, handler, **self.options)
srv.serve_forever()bottle.run( server=ThreadingWSGIRefServer, host='0.0.0.0', port=8080,
interval=1, reloader=False, quiet=True )
ついでにログ抑制もやってみたり。後、Windowsだと特に遅くなるクライアントIPアドレスのDNSリバースlookupをhttp://bugs.python.org/issue6085を参考に外します。まー、ログ出さないなら外す必要も無いんですが、出す出さないでパフォーマンスの変化を見るために一応。
def _bare_address_string(self):
host, port = self.client_address[:2]
return '%s' % hostimport BaseHTTPServer
BaseHTTPServer.BaseHTTPRequestHandler.address_string = \
_bare_address_string
ぐぐる先生はこんなの↓も教えてくれましたがこれはちょっとやり杉。
def getfqdn(name=''):
return name
import socket
socket.getfqdn=getfqdn
quiet=Falseで8.4TPS、quiet=Trueで 10.9TPSって所まで改善。5倍差があると流石にgeventしかないなと思うものの2倍差も無いところまでくるとまーgevent使うことも無いなに変わるから不思議。ログ出すとパフォーマンスは悪くなりますがまぁ良いかと思えなくも無いのでとりあえず出す感じで。
Jolicloud on vaio p インスタントモード入替
ガジェット系の話は別 Blog でやろうと思ってたけどあまりにもこっちの Blog の更新ねたが無いので。
とりあえずこれを。
使ったのは jolicloud の PreFinal。 GMA500 というか poulsbo のドライバは標準で入ってるものの微妙にエラーで X が vesa でしか起動しないので ubuntu 9.10(Karmic) 用のスクリプトでpsb関連を再導入。
HardwareSupportComponentsVideoCardsPoulsbo - Ubuntu Wiki
導入前は非常に遅い。使えない。アイコンのエフェクトとか駄目駄目。画面狭いといい事なしですがドライバ導入でいい感じに。アプリ起動時にアイコンがクルって回るのが可愛くてお気に入り。Firefox, chrome が普通に使えるしインストール後のサイズが2G程度、日本語入力も簡単に設定できる。
Ubuntu notebook rimix とか moblin とか chromeos とか android も色々試したんだけど今ひとつ気に入らず。jolicloud は気に入っています。XMB捨ててでも入れ替える価値あり。
XMBボタンで起動出来るインスタントモードは巷で言われているように kernel.pam と initrd.pam で kernel と initrd が指定されてます。って事でそれを書き換えればOK…。とは行かないのが悩みの種。
インスタントモードの構成ファイル中、 rootfs とか menu が ext2 でマウントできるのに対し initrd だけはフォーマット不明。 tar とか gzip とか bzip2 とか cpio とか lzma とか lzo とか cramfs とか色々試したけど不明。 kernel.pam って corel の Instant on の機能のように言われてるけど本家Instant on自体は grub2 使ってるみたいでこの kernel.pam を利用するブートローダーは EFI の InsydeH2O の機能の様な気がします。
それはさておき windows パーティションに rootfs のファイルを置いて loop マウントしたかったのでどうしても initrd が必要…でも上の通り inited のフォーマットがわからず、試しにcpio+gzなinitrdを置いても読んでくれない。Instantモードでxterm起動して見てみると device ram0 で minixfs なので initrdなのは間違いないんだけど…。
って事で逃げ手で、Linux の 2.6 から使える initramfs を使って kernel に initrd を抱き合わせました。昔ってinitrd.gzを単純に連結したらOKだった気がするんだけどARMだったかな。うろ覚え。initramfs は kernel を再構築する必要が有ります。
kernel再構築時、.configのCONFIG_INITRAMFS_SOURCEにinitrdのディレクトリを指定するだけ。インストールした jolicluod から /initrd.gz を持ってきて展開。後、loopbackマウント用にchroot周りシェル書かないと駄目かもと思ってたんだけどjolicloudの(ubuntuの)/initが優秀でオプションだけでいけました。bzImageサイズが10M超で駄目かとも思ってたけどこれも無事読み込んでるみたいで危惧に終わりました。駄目だったらkernel.pamからgrub起動して(realmodeに戻る必要が有るけど)そこからkernel起動かとかも思ってたもののそこまでせずに済んで一安心。
起動時間短縮のために不要kmod削除しようかと思ったもののまぁ我慢できるレベルって事で。今後の改善点。
ここ一年弱Pがメインマシンです。AndroidとかLinuxとかビルドしたり画像系の作業する時は流石にデスクトップでやってますがpythonのGAEぐらいならPで十分。
HTML5とflashとIE6
正直、chromeでHTML5がサポートされつつ有るし、
websocketsすげーって思ってる自分としては、
何となくFlashが嫌いでHTML5頑張れー、
Adobe製品に負けないようなオーサリングソフト出てこいー、
って思ってたけど。
Chrome 4.0がリリースされた
Chrome 4.0がリリースされた。ということはWebSocketが普通に使えるようになったということ。
HTML5は勧告が2012年だから・・・って言われたりもするけど、
Chromeとsafariで使えればそれでいいやと言う感じ。
golangはリリース多すぎ。
多すぎてプロダクションにはちょっとねーと言われたりもするけど、
ま、それはそれ。
Python、Rubyですらちょっとねーと言われるようなIT業界も有るから適材適所使われるところでは使われるでしょう。