微框架實測評比
大學生涯以來,自己累積了一些web 端的 side projects。 但是考量開發、維護與運算成本,使用萬能的Django 也許不是最佳的方法。因為Django 的的架構複雜性太高,維護成本也相對的高。使用在重要性低又簡單的 side project 實在不太適合 ( 90% 的專案不就是做 CRUD )。
作為Python 支持者,我趁著週末測試了8款微框架:
- aiohttp
- Bottle
- Flask
- Japronto
- Pyramid
- Sanic
- Starlette
- Tornado
測試的目的是評估他們的穩定性、輕量性、支援性。由於自己先前用過了 Flask, Sanic, aiohttp 寫自己 side project。我也會針對這三個說說我的使用體驗。
1. 實驗結果
第一個實驗結果是在本地端開啟負載工作與伺服器,這個目的是為了降低網路飽和問題。
每個框架會透過Locust分別進行json 與文字的負載測試。所施加的負載是4000同時在線發出請求長達 2分鐘。在json的負載測試結果如下。
非同步的部分由 uvloop 取代 asyncio。
Framework | Total Request | Request Per Second | Median Response Time (ms) | Failed Requests |
---|---|---|---|---|
aiohttp | 23459 | 11 | 392.48 | 0 |
Bottle | 20778 | 74 | 350.93 | 163 |
Flask | 19809 | 82 | 333.80 | 0 |
Japronto | 24058 | 7 | 406.88 | 0 |
Pyramid | 20912 | 74 | 350.75 | 233 |
Sanic | 16877 | 120 | 285.45 | 2 |
Starlette | 17216 | 120 | 290.92 | 1 |
Tornado | 23993 | 8 | 406.02 | 0 |
text 負載結果跟 json 差不多。詳細可以看這個repo
第二個實驗結果是要看在網路限制下,各家框架在10,000同時連線的表現。我在 Linode 上租用了一個在日本的 Nanode ( 1vCPU, 1GB RAM ),並使用交大 1Gbps 的網路進行相同的負載測試。
Framework | Total Request | Request Per Second | Median Response Time (ms) | Failed Requests |
---|---|---|---|---|
aiohttp | 18924 | 317.42 | 63 | 0 |
Bottle | 13402 | 225.04 | 120 | 0 |
Flask | 13393 | 224.14 | 120 | 0 |
Japronto | 19003 | 319.82 | 62 | 0 |
Pyramid | 13316 | 223.58 | 120 | 0 |
Sanic | 18525 | 311.76 | 120 | 42 |
Starlette | 17260 | 288.02 | 120 | 3 |
Tornado | 18939 | 317.33 | 63 | 0 |
為了避免作業系統針對單 process的資源限制,可以透過resource套件將上限設定無限大( 在 production 環境就是透過 wsgi 讓多個 process worker 分擔工作 ),減少失敗request 的情況。
相比延遲更大的環境下,aiohttp, Japronto, Tornado 三個反應時間幾乎差不多,說明在不使用 pipeline 的情況三者的效能是差不多的。
關於Japronto在百萬request per second 結果,其實是使用 pipelined 後的結果。這裡的評測是專注在比較各個微框架在瀏覽器的單發行為效能。
2. 框架現況與評價
Framework | WSGI support | Github stars | Pypi 相關套件 | 支援async | 維護團隊數 |
---|---|---|---|---|---|
aiohttp | yes | 7,140 | 586* | Yes | 2 |
Bottle | yes | 6,039 | 70* | No | 1 |
Flask | yes | 42,478 | 642 | No | 4 |
Japronto | no | 6,932 | 2* | Yes | 1 |
Pyramid | yes | 3,071 | 996* | No | 5 |
Sanic | yes | 11,558 | 155* | Yes | 3 |
Starlette | yes | 1,250 | 20* | Yes | 1 |
Tornado | yes | 17,376 | 889* | Yes, callbacks | 2 |
資料統計 11/03/2019
* 直接根據pypi 搜尋結果得出結果比數減1 (去除框架自己)
評價
1. aiohttp
效能最接近nodejs 且 production ready 的微框架。
2. Bottle 主打不依賴任何外掛包裝, 適合超輕量的deployment
3. Flask
老牌Python 微框架,經過無數實彈測試。反正適合
4. Japronto
Pipeline 效能超越go, nodejs, Techempower 評測json serialization 項目位居 26/321
5. Pyramid
由Pylons 組織維護。
6. Sanic
支援 async 的Flask版,API 與架構形式與Flask 非常相似。
7. Starlette
支援ASGI 框架,可以使用 uvicorn 部署。
8. Tornado
早起由FriendFeed 開發, 被Facebook 收購後開源的框架。non blocking I/O 的功能,使得它適合用在各種推送、串流服務。
總結
如果你才剛認識微框架,想要迅速完他可以選擇穩定、老牌的Flask。如果你注重效能,Tornado, aiohttp, 是目前production ready 的微框架。而 Japronto 作為微框架的潛在黑馬,pipeline 功能適合用在內部 API 應用上。
對了,如果你剛好會 nodejs, golang 且追求效能(或是剛好有人喂你生魚片),那就去寫 nodejs/express/loopback/golang 啦。還是執意用Python ?恭喜你,你是忠實的Python粉絲,讓我來潑你冷水。
如果你喜歡我的文章或side projects,可以捐贈我一杯大熱美(大杯美式咖啡)支持我。