Apache、Nginx 與 Node.js 之爭 —— WordPress 與 Ghost 的性能大對決
巨頭之間的終極對決:崛起的新星 Node.js 能否戰勝巨人 Apache 和 Nginx?
我和你一樣,都閱讀過大量散布在互聯網各處的意見或事實,其中有一些我認為是可靠的,而其它的可能是謠傳,讓人難以置信。
我讀過的許多信息是相當矛盾的,有人深信 StackOverflow(比如這個和另一個),而其他人展示了一個清晰的令人驚訝的結果,這在推動我自己去做測試來驗證結論的過程中扮演了重要的角色。
起初,我做了一些思想準備,我認為我可以避免自己進行實際測試來校驗結論的麻煩——在我知道這一切之前我一直這樣認為。
儘管如此,回顧之前,似乎我最初的想法是相當準確的,並且被我的測試再次印證。這個事實讓我想起了當年我在學校學到的愛因斯坦和他的光電效應的實驗,他面臨著一個光的波粒二重性的問題,最初的結論是實驗受到他的心理狀態的影響,即當他期望結果是一個波的時候結果就會是一個波,反之亦然。
也就是說,我堅信我的結果不會在不久的將來被證明二重性,雖然我的心理狀態可能在某種程度上對它們有影響。
關於比較
上面我讀過一份材料具有一種革新的方式,在我看來,需要了解其自然而然的主觀性和作者自身的偏見。
我決定採用這種方式,因此,提前聲明以下內容:
開發者花了很多年來打磨他們的作品。那些取得了更高成就的人通常參考很多因素來做出自己的抉擇,這是主觀的做法;你需要推崇和捍衛你的技術決策。
也就是說,這個比較文章的著眼點不會成為另一篇「哥們,使用適合你的東西就好」的口水文章。我將會根據我的自身經驗、需求和偏見提出建議。你可能會同意其中一些觀點,反對另外一些;這很好——你的意見會幫助別人做出明智的選擇。
感謝 SitePoint 的 Craig Buckler ,重新啟發了我對比較類文章的看法——嘗試重新忘記自我,並試圖讓所有的讀者心悅誠服。
關於測試
所有的測試都在本地運行:
- 英特爾酷睿 i7-2600k,四核八線程的機器
- Gentoo Linux 是用於測試的操作系統
用於基準測試的工具:ApacheBench,2.3 <$Revision: 1748469 $>
測試包括一系列基準,從 1000 到 10000 個請求以及從 100 到 1000 個的並發請求——結果相當令人驚訝。
此外,我還進行了在高負載下測量伺服器功能的壓力測試。
至於內容,主要是一個包含一些 Lorem Ipsum 的標題和一張圖片靜態文件。
Lorem Ipsum 和 ApacheBenchmark
我決定專註於靜態文件的原因是因為它們去除了可能對測試產生影響的各種渲染因素,例如:編程語言解釋器的速度、解釋器與伺服器的集成程度等等。
此外,基於我自身的經驗,平均網頁載入時間很大一部分通常花費在靜態內容上,例如圖片,因此關注哪個伺服器可以節省我們載入靜態內容的時間是比較現實的。
除此之外,我還想測試一個更加真實的案例,案例中我在運行不同 CMS 的動態頁面(稍後將詳細介紹)時對伺服器進行基準測試。
伺服器
正如我用的是 Gentoo Linux,你就知道我的 HTTP 伺服器在一開始就已經經過優化了,因為我在構建系統的時候只使用了我實際需要的東西。也就是說,當我運行我的測試的時候,不會在後台運行任何不必要的代碼或載入沒用的模塊。
Apache、Nginx 和 Node.js 的使用的配置對比
Apache
$: curl -i http://localhost/index.html
HTTP/1.1 200 OK
Date: Sun, 30 Oct 2016 15:35:44 GMT
Server: Apache
Last-Modified: Sun, 30 Oct 2016 14:13:36 GMT
ETag: "2cf2-54015b280046d"
Accept-Ranges: bytes
Content-Length: 11506
Cache-Control: max-age=600
Expires: Sun, 30 Oct 2016 15:45:44 GMT
Vary: Accept-Encoding
Content-Type: text/html
Apache 配置了 「event mpm」。
Nginx
$: curl -i http://localhost/index.html
HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Sun, 30 Oct 2016 14:17:30 GMT
Content-Type: text/html
Content-Length: 11506
Last-Modified: Sun, 30 Oct 2016 14:13:36 GMT
Connection: keep-alive
Keep-Alive: timeout=20
ETag: "58160010-2cf2"
Accept-Ranges: bytes
Nginx 包括幾個調整:sendfile on
、tcp_nopush on
和 tcp_nodelay on
。
Node.js
$: curl -i http://127.0.0.1:8080
HTTP/1.1 200 OK
Content-Length: 11506
Etag: 15
Last-Modified: Thu, 27 Oct 2016 14:09:58 GMT
Content-Type: text/html
Date: Sun, 30 Oct 2016 16:39:47 GMT
Connection: keep-alive
在靜態測試中使用的 Node.js 伺服器是從頭定製的,這樣可以讓它儘可能更加的輕快——沒有使用外部模塊(Node 核心模塊除外)。
測試結果
點擊圖片以放大:
Apache、Nginx 與 Node 的對比:請求負載的性能(每 100 位並發用戶)
Apache、Nginx 與 Node 的對比:用戶負載能力(每 1000 個請求)
壓力測試
Apache、Nginx 與 Node 的對比:完成 1000 位用戶並發的 100000 個請求耗時
我們可以從結果中得到什麼?
從以上結果判斷,似乎 Nginx 可以在最少的時間內完成最多請求,換句話來說,Nginx 是最快的 HTTP 伺服器。
還有一個相當驚人的事實是,在特定的用戶並發數和請求數下,Node.js 可以比 Nginx 和 Apache 更快。
但當請求的數量在並發測試中增加的時候,Nginx 將重回領先的位置,這個結果可以讓那些陷入 Node.js 的遐想的人清醒一下。
和 Apache、Nginx 不同的是,Node.js 似乎對用戶的並發數不太敏感,尤其是在集群節點。如圖所示,集群節點在 0.1 秒左右保持一條直線,而 Apache 和 Nginx 都有大約 0.2 秒的波動。
基於上述統計可以得出的結論是:網站比較小,其使用的伺服器就無所謂。然而,隨著網站的受眾越來越多,HTTP 伺服器的影響變得愈加明顯。
當涉及到每台伺服器的原始速度的底線的時候,正如壓力測試所描述的,我的感覺是,性能背後最關鍵的因素不是一些特定的演算法,而實際上是運行的每台伺服器所用的編程語言。
由於 Apache 和 Nginx 都使用了 C 語言—— AOT 語言(編譯型語言),而 Node.js 使用了 JavaScript ——這是一種 JIT 語言(解釋型語言)。這意味著 Node.js 在執行程序的過程中還有額外的工作負擔。
這意味著我不能僅僅基於上面的結果來下結論,而要做進一步校驗,正如你下面看到的結果,當我使用一台經過優化的 Node.js 伺服器與流行的 Express 框架時,我得到幾乎相同的性能結論。
全面考慮
逝者如斯夫,如果沒有服務的內容,HTTP 伺服器是沒什麼用的。因此,在比較 web 伺服器的時候,我們必須考慮的一個重要的部分就是我們希望在上面運行的內容。
雖然也有其它的功能,但是 HTTP 伺服器最廣泛的使用就是運行網站。因此,為了看到每台伺服器的性能的實際效果,我決定比較一下世界上使用最廣泛的 CMS(內容管理系統)WordPress 和 Ghost —— 內核使用了 JavaScript 的一顆冉冉升起的明星。
基於 JavaScript 的 Ghost 網頁能否勝過運行在 PHP 和 Apache / Nginx 上面的 WordPress 頁面?
這是一個有趣的問題,因為 Ghost 具有操作工具單一且一致的優點——無需額外的封裝,而 WordPress 需要依賴 Apache / Nginx 和 PHP 之間的集成,這可能會導致顯著的性能缺陷。
除此之外,PHP 距 Node.js 之間還有一個顯著的性能落差,後者更佳,我將在下面簡要介紹一下,可能會出現一些與初衷大相徑庭的結果。
PHP 與 Node.js 的對決
為了比較 WordPress 和 Ghost,我們必須首先考慮一個影響到兩者的基本組件。
基本上,WordPress 是一個基於 PHP 的 CMS,而 Ghost 是基於 Node.js(JavaScript)的。與 PHP 不同,Node.js 有以下優點:
- 非阻塞的 I/O
- 事件驅動
- 更新穎、更少的殘舊代碼
由於有大量的測評文章解釋和演示了 Node.js 的原始速度超過 PHP(包括 PHP 7),我不會再進一步闡述這個主題,請你自行用谷歌搜索相關內容。
因此,考慮到 Node.js 的性能優於 PHP,一個 Node.js 的網站的速度要比 Apache / Nginx 和 PHP 的網站快嗎?
WordPress 和 Ghost 對決
當比較 WordPress 和 Ghost 時,有些人會說這就像比較蘋果和橘子,大多數情況下我同意這個觀點,因為 WordPress 是一個完全成熟的 CMS,而 Ghost 基本上只是一個博客平台。
然而,兩者仍然有共同競爭的市場,這兩者都可以用於向世界發布你的個人文章。
制定一個前提,我們怎麼比較兩個完全基於不同的代碼來運行的平台,包括風格主題和核心功能。
事實上,一個科學的實驗測試條件是很難設計的。然而,在這個測試中我對更接近生活的情景更感興趣,所以 WordPress 和 Ghost 都將保留其主題。因此,這裡的目標是使兩個平台的網頁大小儘可能相似,讓 PHP 和 Node.js 在幕後鬥智斗勇。
由於結果是根據不同的標準進行測量的,最重要的是尺度不一樣,因此在圖表中並排顯示它們是不公平的。因此,我改為使用表:
Node、Nginx、Apache 以及運行 WordPress 和 Ghost 的比較。前兩行是 WordPress,底部的兩行是 Ghost
正如你所見,儘管事實上 Ghost(Node.js)正在載入一個更小的頁面(你可能會驚訝 1kb 可以產生這麼大的差異),它仍然比同時使用 Nginx 和 Apache 的 WordPress 要慢。
此外,使用 Nginx 代理作為負載均衡器來接管每個 Node 伺服器的請求實際上會提升還是降低性能?
那麼,根據上面的表格,如果說它產生什麼效果的話,它造成了更慢的效果——這是一個合理的結果,因為額外封裝一層理所當然會使其變得更慢。當然,上面的數字也表明這點差異可以忽略不計。
但是上表中最重要的一點是,即使 Node.js 比 PHP 快,HTTP 伺服器的作用也可能超過某個 web 平台使用的編程語言的重要性。
當然,另一方面,如果載入的頁面更多地依賴於伺服器端的腳本處理,那麼我懷疑結果可能會有點不同。
最後,如果一個 web 平台真的想在這場競賽里擊敗 WordPress,從這個比較中得出的結論就是,要想性能佔優,必須要定製一些像 PHP-FPM 的工具,它將直接與 JavaScript 通信(而不是作為伺服器來運行),因此它可以完全發揮 JavaScript 的力量來達到更好的性能。
作者:Liron 譯者:OneNewLife 校對:wxy
(題圖來自:deviantart.net)
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive