unicornのpython版だとか。
Gunicorn - Python WSGI HTTP Server for UNIX
ubuntuだとaptでbuild-essentialをいれとけば、easy_installやpipで問題なくインストールできるっぽい。
Workerは差し替えが可能らしい。id:mopemope先生のmeinheldには、gunicorn用のWorkerが含まれている。
$ cat myapp.py def app(environ, start_response): data = "Hello, World!\n" start_response("200 OK", [ ("Content-Type", "text/plain"), ("Content-Length", str(len(data))) ]) return iter([data]) $ gunicorn -w 2 -b 0.0.0.0:8000 myapp:app 2010-08-10 00:03:36 [2706] [INFO] Starting gunicorn 0.10.1 2010-08-10 00:03:36 [2706] [INFO] Listening at: http://0.0.0.0:8000 2010-08-10 00:03:36 [2708] [INFO] Booting worker with pid: 2708 2010-08-10 00:03:36 [2709] [INFO] Booting worker with pid: 2709
$ ab -c 100 -n 10000 http://192.168.11.153:8000/
Server Software: gunicorn/0.10.1 Server Hostname: 192.168.11.153 Server Port: 8000 Document Path: / Document Length: 14 bytes Concurrency Level: 100 Time taken for tests: 10.528 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 1601760 bytes HTML transferred: 140154 bytes Requests per second: 949.86 [#/sec] (mean) Time per request: 105.279 [ms] (mean) Time per request: 1.053 [ms] (mean, across all concurrent requests) Transfer rate: 148.58 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 1 52 265.9 26 3051 Processing: 5 36 31.8 30 431 Waiting: 3 28 30.3 22 429 Total: 12 88 268.6 54 3107 Percentage of the requests served within a certain time (ms) 50% 54 66% 81 75% 90 80% 100 90% 103 95% 105 98% 240 99% 271 100% 3107 (longest request)
ちなみに、fapws3だとこんな感じだった。
$ cat myapp2.py import fapws._evwsgi as evwsgi from fapws import base def start(): evwsgi.start("0.0.0.0", "8000") evwsgi.set_base_module(base) def app(environ, start_response): data = "Hello, World!\n" start_response("200 OK", [ ("Content-Type", "text/plain"), ("Content-Length", str(len(data))) ]) return iter([data]) evwsgi.wsgi_cb(("/", app)) evwsgi.run() if __name__ == "__main__": start()
Server Software: fapws3/0.6 Server Hostname: 192.168.11.153 Server Port: 8000 Document Path: / Document Length: 14 bytes Concurrency Level: 100 Time taken for tests: 14.429 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 1360000 bytes HTML transferred: 140000 bytes Requests per second: 693.04 [#/sec] (mean) Time per request: 144.292 [ms] (mean) Time per request: 1.443 [ms] (mean, across all concurrent requests) Transfer rate: 92.04 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 90 471.5 9 9000 Processing: 6 40 28.5 32 309 Waiting: 2 32 26.5 27 308 Total: 7 131 481.1 36 9019 Percentage of the requests served within a certain time (ms) 50% 36 66% 106 75% 113 80% 113 90% 115 95% 116 98% 3081 99% 3098 100% 9019 (longest request)
次、meinheld。
$ cat myapp3.py from meinheld import server def app(environ, start_response): data = "Hello, World!\n" start_response("200 OK", [ ("Content-Type", "text/plain"), ("Content-Length", str(len(data))) ]) return iter([data]) server.listen(("0.0.0.0", 8000)) server.run(app)
Server Software: meinheld/0.1.2 Server Hostname: 192.168.11.153 Server Port: 8000 Document Path: / Document Length: 14 bytes Concurrency Level: 100 Time taken for tests: 11.143 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 1400000 bytes HTML transferred: 140000 bytes Requests per second: 897.44 [#/sec] (mean) Time per request: 111.429 [ms] (mean) Time per request: 1.114 [ms] (mean, across all concurrent requests) Transfer rate: 122.70 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 1 67 419.6 3 3010 Processing: 12 41 32.0 35 712 Waiting: 1 39 32.5 34 712 Total: 12 108 424.4 38 3104 Percentage of the requests served within a certain time (ms) 50% 38 66% 43 75% 52 80% 57 90% 90 95% 96 98% 3030 99% 3070 100% 3104 (longest request)
gunicornでmeinheldのWorkerを使ってみる
$ gunicorn -w 2 --worker-class="meinheld.gmeinheld.MeinheldWorker" -b 0.0.0.0:8000 myapp:app
Server Software: meinheld/0.1.2 Server Hostname: 192.168.11.153 Server Port: 8000 Document Path: / Document Length: 14 bytes Concurrency Level: 100 Time taken for tests: 10.751 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 1400000 bytes HTML transferred: 140000 bytes Requests per second: 930.14 [#/sec] (mean) Time per request: 107.511 [ms] (mean) Time per request: 1.075 [ms] (mean, across all concurrent requests) Transfer rate: 127.17 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 1 67 414.6 16 9016 Processing: 9 30 42.5 21 750 Waiting: 1 28 42.3 19 749 Total: 13 98 417.9 36 9037 Percentage of the requests served within a certain time (ms) 50% 36 66% 40 75% 44 80% 49 90% 90 95% 93 98% 286 99% 3038 100% 9037 (longest request)
Xen上で動かしてるからなのかはわからないけど、全体的にabの結果にばらつきがあった。
少なくともgunicorn自体は遅いとかはないっぽい?運用面で有利だったりするのかな。