Go和Python Web服務器性能對比
我通常使用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 例子。任何應用都包括:
◆ 使用正則表達式通過 URL 路徑傳遞參數;
◆ 使用語句創建多行輸出;
◆ 使用 printf 形式的格式化函數/表達式格式化輸出。
我想,這些都是在 Web 應用中常見的操作,所以應當包含在任何簡易的性能對比測試中。所有測試應用的代碼在下面的鏈接中:
◆ Go http
◆ web.go
◆ twister
◆ web.py
測試環境
測試環境包括兩臺 使用千兆以太網鏈接的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 應用)。
原文:http://www.oschina.net/question/25940_19172
【編輯推薦】