Python常見Web框架性能對比(一)

首先:

  • 沒有專用的服務器
  • 沒有測試專用的代碼片段
  • 沒有牛人背書

這只是一個簡單的對比: 用一臺普通的機器,以盡量相同的方式分別部署不同Web框架編寫的一段簡單程序.然后使用壓力測試程序run一下,做個chart出來.直觀的反應一下. .python的常用框架性能之間的差別.較真的杠精現(xiàn)在就可以出門左轉(zhuǎn)了.

先要介紹一下我的測試環(huán)境: acer的商務機,具體配置是酷睿8,8g,1t的5400轉(zhuǎn)機械硬盤, 操作系統(tǒng)是ubuntu 18.04 desktop

本次使用的代碼特別簡單,所以因為個人能力不濟造成性能下降的可能性比較小,哈哈.本次測試的是一些常用的python的Web開發(fā)框架.下面有請選手登場:

  • Django 不用說,最早進入中國的python web框架之一, 一站式結構, 文檔齊全, 功能強大.用戶眾多,入坑首選之一
  • Flask 知名度和Django在伯仲之間的python web框架,和相對重型的Django不同,flask標榜自己的輕量級, 做個單純的web框架,只負責路由和視圖部分,其他的交給插件部分(flask眾多的插件也是亮點之一).入坑首選之二
  • AioHttp 一個異步的web框架,包含服務端和客戶端,推薦python 3.5+, 視圖函數(shù)是異步寫法.也是因為異步,所以性能出色.
  • Sanic 也是異步類flask的web框架,無需插件即支持websocket,因為是類flask框架,所以從flask 轉(zhuǎn)過來的話無論學習還是維護成本都是極低的.性能自己說也是非常高的.在國外有大量的生產(chǎn)環(huán)境案例. 插件/中間件很豐富.
  • Tornado 是一個facebook開源的異步框架,自己的文檔說速度相當快,國內(nèi)也有很多人這么說,我不怕劇透,其實他的性能從4.2時代就已經(jīng)很落伍了.而且由于他的異步機制是自己搞的一套.很多東西寫法都很獨特.學習成本較高.所以,本人是不推薦學習的.也沒任何優(yōu)勢而已,這里把他拉出來就是為了襯托同行.
  • Bottle 一個超簡潔的輕量級web框架.(5年之前)以性能著稱.同步模式.國外國內(nèi)都不算應用廣.比flask更簡潔,但是插件也比較少.
  • Falcon 這個國內(nèi)用的不多,但是國外用戶還是很多的.以安全穩(wěn)定著稱(就是所謂的線程安全那種,你懂的),自說是性能和安全的最佳平衡.有很多生產(chǎn)環(huán)境的案例.主要是用于提供接口服務. 語法稍微繁瑣一點.
  • Vibora 一個很新的異步模式的類flask的web框架,flask開發(fā)者友好(要搶flask的飯碗?),性能也是變態(tài)的好.個人覺得不錯.(畢竟類flask的框架,對插件的依賴是可有可無的)

很多人都知道Python語言的代碼,以運行緩慢著稱(我這是引用眾數(shù)的觀點.不抬杠),所以很多人詬病Python的web框架運行緩慢.不過,個人的觀點是: 實務中, 特別當你不是那么大的分布式的部署的時候,性能瓶頸往往是壓在數(shù)據(jù)庫而不是web框架上.你可以根據(jù)自己的網(wǎng)站/業(yè)務的訪問量計算一下你選中的Web框架是否能滿足你的需求?

測試代碼就是各自的文檔中的hello world代碼.部署上能用gunicorn的就用,有些部署比較特殊的框架那沒辦法,總是,盡量減少部署方式上的差異(python的web框架,部署方式對性能的影響還是非常大的).

測試方式使用siege做并發(fā)壓力測試,從50客戶端開始,每次測試遞增50個客戶端,一直到最后1000個客戶端,每次5000個事務請求. 每個框架做400批次壓力測試.最后的結果清洗后做個統(tǒng)計,使用pygal生成圖表. x軸是客戶端數(shù)量,y軸是每秒處理多少事務(TPS),所有的測試結果都是100%完成.

測試結果

Django

Django_bar.png

Flask

Flask_bar.png

Bottle

Bottle_bar.png

Falcon

Falcon_bar.png

從這里開始,都是異步的框架了

Tornado

Tornado_bar.png

Sanic

Sanic_bar.png

AioHttp

AioHttp_bar.png

Vibora

Vibora_bar.png

全家福

total_bar.png

個人總結:

  • 無論同步還是異步模式,所有的框架在低并發(fā)(50客戶端以內(nèi))性能都是出奇的好.如果使用QPS的換算公式的話.你會發(fā)現(xiàn),如果一般性類的網(wǎng)站(企業(yè)門戶,個人博客之類),速度上完全沒問題.
  • 并發(fā)能力上來說,Django和Flask難兄難弟日常墊底兒.但這并不影響他們的廣泛應用.而且,即使是他們的墊底性能,也能在1000客戶端的情況下維持每秒1000上下的TPS.坦白的說,這算不上高性能,但是滿足絕大多數(shù)站點(尤其是創(chuàng)業(yè)初期的產(chǎn)品原型)的需求是沒問題了.
  • 同步工作模式和異步工作模式相比,并發(fā)能力上全面落后挨打.甚至被秒殺.但是,異步工作模式在代碼書寫上是有要求的(有些coder常說的一步異步,處處異步并不是沒有道理的).并且異步提升的是單位時間的處理能力.在你的服務器崩潰之前,異步工作模式并不會提供更高的處理能力.
  • Tornado 成也性能,敗也性能.在異步的時代,tornado以較高學習成本,捉急的性能,讓成為拍在沙灘上的前浪.至少現(xiàn)在.不要說tornado的性能高什么的了.
  • Vibora 性能確實變態(tài). 即使1000客戶端,也能維持超過1萬的TPS.值得關注一下.

以上是空載的數(shù)據(jù),如果加上本地的數(shù)據(jù)庫負載(原子操作).所有的框架沒有任何差別.瓶頸都在數(shù)據(jù)庫IO上.

python的web框架多如牛毛(遠不像國內(nèi)的翻來覆去django,flask,tornado三大件).特點也是千差萬別.基本上越新的框架越有后發(fā)的優(yōu)勢,我會在工作之余,做一些相關的對比工作.

代碼片段(Hello World):

測試代碼引自官方文檔,未做任何優(yōu)化.

Falcon
# -*- coding: utf-8 -*-
import falcon
from wsgiref import simple_server


app = falcon.API()


class ThingsResource(object):
    def on_get(self, req, resp):
        """Handles GET requests"""
        resp.status = falcon.HTTP_200  # This is the default status
        resp.body = ("Hello Falcon!")


things = ThingsResource()
app.add_route('/query/', things)


if __name__ == "__main__":
    httpd = simple_server.make_server('127.0.0.1', 8086, app)
    httpd.serve_forever()
AioHttp
# -*- coding: utf-8 -*-
from aiohttp import web


route = web.RouteTableDef()
app = web.Application()
port = 8084


@route.get('/query/')
async def hello_world(request):
    return web.Response(text="Hello, Aio!")


async def my_web_app():
    app = web.Application()
    app.add_routes(route)
    return app



if __name__ == '__main__':
    web.run_app(app=my_web_app(), host="0.0.0.0", port=port)
Bottle
# -*- coding: utf-8 -*-
from bottle import route, run, default_app


app = default_app()


@route('/query/')
def index():
    return "Hello Bottle!"


if __name__ == "__main__":
    run(app=app, host='0.0.0.0', port=8082, server="tornado")
Flask
# -*- coding: utf-8 -*-
from flask import Flask

app = Flask(__name__)


@app.route('/query/')
def hello_world():
    return 'Hello Flask!'


if __name__ == '__main__':
    app.run()
Sanic
# -*- coding: utf-8 -*-
from sanic import Sanic
from sanic import response


app = Sanic()


@app.route("/query/")
async def test(request):
    request
    return response.text("Hello Sanic!")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8083, debug=True)
    pass
Tornado
# -*- coding: utf-8 -*-
import tornado.ioloop
import tornado.web
from tornado.httpserver import HTTPServer
from tornado import gen
from tornado.ioloop import IOLoop


class MainHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        self.write("Hello, Tornado!")

def make_app():
    return tornado.web.Application([
        (r"/query/", MainHandler),
    ])


if __name__ == "__main__":
    app = make_app()
    server = HTTPServer(app)
    app.listen(8085)
    server.start(0)  # forks one process per cpu
    print("tornado server run on 8085....")
    IOLoop.current().start()

沒有django的是因為django的代碼太多,不方便貼. 有興趣的自己去django手冊看一下就好了.

寫在最后

python的框架遠遠不止上面說的哪些, 可以說, 如果你想尋找一款最好的python開發(fā)框架,抱歉這個真沒有.每個框架都有其存在的價值或者意義,盡管在某些方面看起來有些過時.和某些一兩個框架獨大的語言不同.python語言的框架是一種百花齊放百家爭鳴的狀態(tài). 不過大體來說, python的web開發(fā)框架分2大類:

  • 全能型的一站式框架
  • 自助式的微框架

一站式框架

一站式框架提供了從路由,ctos,模板渲染,中間件, web-socket支持和orm等你想到的想不到的各種功能.有什么問題,看文檔就行了. 語法的一致性好. 新需求導致的學習成本曲線平緩. 不太容易掉坑里. 一站式框架的典型代表是 Django.(發(fā)音類似: 姜戈,前面的d不發(fā)音)

微框架

微框架就是那種只提供基本功能的框架.在python中,這種提供單一功能的微框架忒多. 比如Flask僅僅提供了路由,藍圖之類的基本功能.(Flask模板還是借助jinja2來實現(xiàn)的,當然你也可以使用其他模板). 其他的功能,都需要你借助插件或者庫來完成.比如說ORM方面,sqlalchemy, peewee, pony這些orm框架僅僅提供orm功能.你可以接觸插件或者自己手工和web框架組合在一起工作. 當然和一站式框架相比,稍微多一些的學習成本.換來的是更多的選擇甚至更高的性能.

  • 一站式就像管家一樣,什么不會就問管家,除非管家說我也不會,那你就基本傻眼了.
  • 微框架就像個工具人. 而你是項目經(jīng)理. 它負責做自己份內(nèi)事.你的能力決定最終結果.
  • 一站式框架坑少. 選擇入門初期提升快, 但中后期可能會遇到受框架設計思想約束的問題.
  • 微框架更開放一些, 有可能坑比較多,入門相對難一些. 但由于微框架對開發(fā)者的約束較少. 吃透了以后, 容易達到一種一通百通的狀態(tài)(微框架的設計思維上基本都是想通的). 中后期在業(yè)務處理上會比較得心應手.相對的技術??梢匝由斓母鼜V.

如何選擇

django和flask是入門首選.他們共同的特點就是成熟穩(wěn)定. 兩者都已經(jīng)在生產(chǎn)環(huán)境經(jīng)受過大量考驗.性能雖然平庸,但穩(wěn)如老狗. 業(yè)務上基本上是百搭型. github上兩者都是51K+的星.根據(jù)個人喜愛可以二選一. 2者之間的差別主要是來源于自身的設計思維:

如果你打算長期從事python開發(fā)工作,我推薦你用微框架的一站式入門. 雖然開始會多一些磕磕絆絆,但你后來的道路會走的更寬敞. 如果你只是python的web框架輕度用戶.無疑學習django見效更快. 當然,你的性格也會影響選擇: django的開發(fā)者,需要遵守的約定更多一些. 性格上守序一點會比較好(會java的人會有是曾相識的感覺).flask的開發(fā)者需要遵守的約定比較少. 語法上也是更貼近于python提倡的簡潔直白的風格 . 崇尚真我風格的年輕人可能更容易接受一些.

工作上是框架跟著業(yè)務走, 你不能先選擇一個框架,讓后讓業(yè)務向框架的技術特點妥協(xié).而是根據(jù)當前業(yè)務選擇最適合的開發(fā)框架. 業(yè)務的需求是動態(tài)變化的.如果你當前的框架滿足不了業(yè)務發(fā)展的需要, 那就選擇一個能滿足的業(yè)務需要的框架和當前的框架配合是使用. 因為你不能期望總有一個框架你滿足你的業(yè)務發(fā)展中的所有需求.微框架因為其低耦合的特性.更容易迎合業(yè)務的變化. 這也是我推薦選擇flask這種類型的微框架作為入門的原因之一.

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Python程序員有很多很好的選擇來創(chuàng)建Web應用程序和API;Django,Weppy,Bottle和Flask...
    顧家樂1020閱讀 711評論 0 4
  • 寫在前面:本文的數(shù)據(jù)涉及到我面試時遇到過的問題,大概一次 http 請求到收到響應需要多少時間。這個問題在實際工作...
    Tim_Lee閱讀 53,264評論 4 62
  • 他,悄悄的趕腳歸來,他,悄悄的讓萬物在蘇醒中萌芽,他,有一種神奇的功效,讓沉睡的人們迅速驚醒,他,時間最短,在人不...
    美好的機器貓閱讀 531評論 0 0
  • 幾點零星的社群思考,于3月4日記。 1,社群依然在增加,流量依舊匯聚在社群 就目前而言,社群的整體的數(shù)量依然是在增...
    剎那流轉(zhuǎn)閱讀 487評論 0 17
  • 思維在以做數(shù)學難題兩到三倍的速度運轉(zhuǎn),心跳也在加速,四肢開始變得麻木…… 一個人的房間,我在床上躺著…...
    緣起天意閱讀 274評論 0 2

友情鏈接更多精彩內(nèi)容