這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Go和Python Web伺服器效能對比
2011-08-05 13:41 renwofei423 開源中國社區 我要評論(0) 字型大小:T | T
我通常使用Python來構建Web 應用程式。一年前,在興趣的驅使下,我開始學習Go。我發現,有 http、mustache.go GoMySQL 包的 Go 可以是我用來工作的不錯的工具組合。因此,我決定使用Go編寫我的應用程式
AD:2013雲端運算架構師峰會精彩課程曝光
我通常使用Python來構建Web 應用程式。一年前,在興趣的驅使下,我開始學習Go。 在此期間,我重寫了一些原本由C 開發的CGI 應用,包括運行於 chroot 環境下的同 thttpd 伺服器一起的應用。我開始尋找可以開發易於 chroot、且內建 Web 服務器的獨立 Web 應用程式的工具。那時,我開始玩 web.go 架構、mustache.go 模板、Go 原生 http 包和 GoMySQL 資料庫 API。我發現,有 http、mustache.go GoMySQL 包的 Go 可以是我用來工作的不錯的工具組合。因此,我決定使用Go編寫我的應用程式。(Go程式設計語言也可以用來編寫Web應用?)
在工作過程中發現,我需要比 mustache.go 更加靈活,比 GoMySQL 更加成熟、沒有那麼多 Bug 的東西。最終,我使用 Kasia.go 模板和 MyMySQL (為我的應用程式定製開發的包,不過我將其貢獻給了 Go 社區)。重寫的應用即便是在比以前的負載更高的運營環境下,也工作得很好。我開始思考這個問題:用 Go 實現獨立 Web 應用程式比 Python 到底快了(或者是慢了)多少。我決定做一些各種架構和伺服器不同的用途的測試。為了比較,我選擇了下面的 Go 包:
◆ 原始的 Go http包;
◆ web.go 架構(它使用運行於獨立模式[standalone mode] 的 http 包);
◆ twister 架構 (它同樣使用 http 包)。
和下面的 Python Web伺服器/架構:
◆ 使用 CherryPy WSGI 伺服器的 web.py 架構;
◆ 使用 flup FastCGI 做 nginx 伺服器的幕後處理的 web.py 架構;
◆ tornado 非同步伺服器/架構;
◆ nginx 做負載平衡的 tornado。
每一個用例,我都編寫了一個小應用,略微複雜一些的、傳統的 Hello World 例子。任何應用都包括:
◆ 使用Regex通過 URL 路徑傳遞參數;
◆ 使用語句建立多行輸出;
◆ 使用 printf 形式的格式化函數/運算式格式化輸出。
我想,這些都是在 Web 應用程式中常見的操作,所以應當包含在任何簡易的效能對比測試中。所有測試應用的代碼在下面的連結中:
◆ Go http
◆ web.go
◆ twister
◆ web.py
◆tornado
測試環境
測試環境包括兩台 使用千兆乙太網路連結的PC (請求發起者和應用伺服器)。
◆ 請求發起者:2 x Xeon 2.6 GHz with hyperthreading, Debian SID, kernel: 2.6.33.7.2-rt30-1-686 #1 SMP PREEMPT RT;
◆ 伺服器: MSI Netbook with two core Intel U4100 1.30GHz, AC power connected, 64-bit Ubuntu 10.10, kernel: 2.6.35-25-generic #44-Ubuntu SMP, Python 2.6.6-2ubuntu2, web.py 0.34-2, flup 1.0.2-1, tornado 0.2-1, nginx 0.7.67-3ubuntu1;
為了產生 HTTP 要求並且評估測試應用的效能,我使用 siege 效能測試工具。Siege 可以用多線程類比多個使用者。我使用了下面的命令產生請求:
siege -c 200 -t 20s http: //SERVER_ADDR :8080 /Hello/100
或者多個類似的命令,減少參數 -c 的量(在這個測試中,我同時運行了多個 Python 指令碼)。它類比了 200 使用者的請求,並持續 20 秒。這個 URL 使得 Web 應用程式對每個請求都輸出 100 行。Go 應用使用 Go 發布版 2011-02-01.1。
結果
GOMAXPROCS=1, 一個 Python 進程:
架構 |
請求速率 [1/sec] |
Go http |
1350 |
Twister |
1324 |
Web.go |
1141 |
Tornado |
882 |
Tornado+nginx |
862 |
Web.py+CheryPy |
169 |
Web.py+nginx |
114 |
GOMAXPROCS=2, 兩個 Python 並發進程:
GOMAXPROCS=4, 四個 Python 並發進程:
Web.py+nginx 工作的 flup FastCGI 選項:multiplexed=False, multithreaded=False。如果 multiplexed=True 它會運行得慢一些。如果 multithreaded=True 而只有一個進程服務於 nginx 伺服器,會報下面的錯誤:
結論
你可以看到 Go 贏得了幾乎所有的測試案例。web.go 架構的那個不太理想的結果可能是由於它先嘗試用指定的 URL 尋找靜態頁面,然後才會執行處理方法。讓我驚訝的是 tornado Python 架構如此之高的效能,尤其是跟 web.py 架構相比而言。我同樣對 CherryPy 伺服器比 nginx+flup 快感到驚訝 (我使用 web.py+flup+nginx 跑幾乎所有的 Python Web 應用程式)。