這三個都是Python WSGI的web開發框架,到底用哪個呢?單純從性能的角度而言,可能哪個快就用哪個,但是這也不是絕對的。比如我就比較喜歡webpy的router配置放在一個文件中,而flask和bottle的配置分散到各個文件中,從開發角度,寫在哪里無所謂,但是從閱讀的角度,webpy就比較方便了。因為在工作中本着拿來主義的角度使用了webpy,但是看起來flask也很火,而bottle據說更是一個精簡的文件,所以本文簡單測試了三者的性能,供參考。
測試方法:用三者分別寫一個URL API,這個API直接返回“hello world!”字符串,用uwsgi啟動python應用。客戶端采用apache benchmark工具:ab,對server執行500000次請求,並發為1000,然后比較ab的測試結果,同時用統計機器的CPU消耗。
測試腳本:http://pan.baidu.com/s/1URGJ0,提取密碼:6thp
測試結果:
CPU曲線圖(測試順序:webpy,sleep 120秒,flask,sleep 120秒,bottle)
- webpy
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
……
Completed 50000 requests
Completed …… requests
Finished 500000 requests
……
Server Port: 8010
Document Path: /
Document Length: 12 bytes
Concurrency Level: 1000
Time taken for tests: 1533.489 seconds
Complete requests: 500000
Failed requests: 24246
(Connect: 0, Receive: 0, Length: 24246, Exceptions: 0)
Write errors: 0
Total transferred: 14748374 bytes
HTML transferred: 5709048 bytes
Requests per second: 326.05 [#/sec] (mean)
Time per request: 3066.978 [ms] (mean)
Time per request: 3.067 [ms] (mean, across all concurrent requests)
Transfer rate: 9.39 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 10.1 1 3000
Processing: 111 2962 7581.0 645 69933
Waiting: 0 1629 3949.2 642 68942
Total: 218 2963 7581.6 646 69933
Percentage of the requests served within a certain time (ms)
50% 646
......
100% 69933 (longest request)
- flask
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
......
Completed 50000 requests
......
Completed 500000 requests
Finished 500000 requests
......
Server Port: 8020
Document Path: /
Document Length: 12 bytes
Concurrency Level: 1000
Time taken for tests: 862.997 seconds
Complete requests: 500000
Failed requests: 17067
(Connect: 0, Receive: 0, Length: 17067, Exceptions: 0)
Write errors: 0
Total transferred: 43946903 bytes
HTML transferred: 5795196 bytes
Requests per second: 579.38 [#/sec] (mean)
Time per request: 1725.993 [ms] (mean)
Time per request: 1.726 [ms] (mean, across all concurrent requests)
Transfer rate: 49.73 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 42.4 1 3002
Processing: 40 1635 6311.8 196 69819
Waiting: 0 725 3301.8 195 69030
Total: 71 1636 6312.6 197 69819
Percentage of the requests served within a certain time (ms)
50% 197
......
100% 69819 (longest request)
- bottle
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
......
Completed 50000 requests
......
Completed 500000 requests
Finished 500000 requests
......
Server Port: 8030
Document Path: /
Document Length: 12 bytes
Concurrency Level: 1000
Time taken for tests: 419.576 seconds
Complete requests: 500000
Failed requests: 4111
(Connect: 0, Receive: 0, Length: 4111, Exceptions: 0)
Write errors: 0
Total transferred: 45125899 bytes
HTML transferred: 5950668 bytes
Requests per second: 1191.68 [#/sec] (mean)
Time per request: 839.153 [ms] (mean)
Time per request: 0.839 [ms] (mean, across all concurrent requests)
Transfer rate: 105.03 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 21 256.5 1 9015
Processing: 9 709 3949.7 117 69845
Waiting: 0 460 2441.9 116 67652
Total: 29 730 3957.6 119 69846
Percentage of the requests served within a certain time (ms)
50% 119
......
100% 69846 (longest request)
結果分析:
(1)從平均的response time:bottle(0.839) < flask(1.726) < webpy(3.067)
(2)從TPS:bottle(1191.68) > flask(579.38) > webpy(326.05)
(3)從Failed請求數:bottle(1191.68) > flask(579.38) > webpy(326.05)
[注]:為什么會有fail?從uwsgi的log看來,報了一些(Write IO Error),這個錯誤的原因是當uwsgi處理完請求返回結果時,發現客戶端已經斷開了連接,結果無處可送,則Writer IO Error。一般情況下,這是由於客戶端響應太慢,導致了客戶端timeout所致。看起來響應還是足夠快的,並且並發只有1000,這里為何會timeout,不是十分確定根本原因。
(4)從CPU:
- webpy最耗CPU,其中黃色部分是(CPU system time),看起來系統調用比其余兩個高很多。
- bottle比flask略高一些,總體是上,相差不算過大。
結論:性能排序結果為webpy < flask < bottle。
那是不是就意味着應該選性能最好的bottle?這也不應太絕對,因為在開發項目時,不同的人可能對不同的項目的熟悉程度不一樣,另外flask可能有廣泛的插件支持,所以選擇最適合自己的,而不是一昧追求性能最快。
說明:本文試圖比較三者之間的性能,而不是測試三個模塊的性能極限(例如我都沒有說明測試機的配置,因為這里測試的是同一配置下的相對值)。如果測試三個模塊的性能極限,可能server配置、以及uwsgi的配置均需要根據測試進行優化,在這里不是重點,不再贅述。

