巨頭之間的終極對決:崛起的新星 node.js 能否戰勝巨人 apache 和 nginx?
我和你一樣,都閱讀過大量散布在網際網路各處的意見或事實,其中有一些我認為是可靠的,而其它的可能是謠傳,讓人難以置信。
起初,我做了一些心理準備,我認為我可以避免自己進行實際測試來校驗結論的麻煩——在我知道這一切之前我一直這樣認為。
盡管如此,回顧之前,似乎我最初的想法是相當準确的,并且被我的測試再次印證。這個事實讓我想起了當年我在學校學到的愛因斯坦和他的光電效應的實驗,他面臨着一個光的波粒二重性的問題,最初的結論是實驗受到他的心理狀态的影響,即當他期望結果是一個波的時候結果就會是一個波,反之亦然。
也就是說,我堅信我的結果不會在不久的将來被證明二重性,雖然我的心理狀态可能在某種程度上對它們有影響。
<a target="_blank"></a>
上面我讀過一份材料具有一種革新的方式,在我看來,需要了解其自然而然的主觀性和作者自身的偏見。
我決定采用這種方式,是以,提前聲明以下内容:
開發者花了很多年來打磨他們的作品。那些取得了更高成就的人通常參考很多因素來做出自己的抉擇,這是主觀的做法;你需要推崇和捍衛你的技術決策。
也就是說,這個比較文章的着眼點不會成為另一篇“哥們,使用适合你的東西就好”的口水文章。我将會根據我的自身經驗、需求和偏見提出建議。你可能會同意其中一些觀點,反對另外一些;這很好——你的意見會幫助别人做出明智的選擇。
所有的測試都在本地運作:
英特爾酷睿 i7-2600k,四核八線程的機器
用于基準測試的工具:apachebench,2.3 <$revision: 1748469 $>
測試包括一系列基準,從 1000 到 10000 個請求以及從 100 到 1000 個的并發請求——結果相當令人驚訝。
此外,我還進行了在高負載下測量伺服器功能的壓力測試。
至于内容,主要是一個包含一些 lorem ipsum 的标題和一張圖檔靜态檔案。

lorem ipsum 和 apachebenchmark
我決定專注于靜态檔案的原因是因為它們去除了可能對測試産生影響的各種渲染因素,例如:程式設計語言解釋器的速度、解釋器與伺服器的內建程度等等。
此外,基于我自身的經驗,平均網頁加載時間很大一部分通常花費在靜态内容上,例如圖檔,是以關注哪個伺服器可以節省我們加載靜态内容的時間是比較現實的。
除此之外,我還想測試一個更加真實的案例,案例中我在運作不同 cms 的動态頁面(稍後将詳細介紹)時對伺服器進行基準測試。
正如我用的是 gentoo linux,你就知道我的 http 伺服器在一開始就已經經過優化了,因為我在建構系統的時候隻使用了我實際需要的東西。也就是說,當我運作我的測試的時候,不會在背景運作任何不必要的代碼或加載沒用的子產品。
apache、nginx 和 node.js 的使用的配置對比
<code>$: curl -i http://localhost/index.html</code>
<code></code>
<code>http/1.1 200 ok</code>
<code>date: sun, 30 oct 2016 15:35:44 gmt</code>
<code>server: apache</code>
<code>last-modified: sun, 30 oct 2016 14:13:36 gmt</code>
<code>etag: "2cf2-54015b280046d"</code>
<code>accept-ranges: bytes</code>
<code>content-length: 11506</code>
<code>cache-control: max-age=600</code>
<code>expires: sun, 30 oct 2016 15:45:44 gmt</code>
<code>vary: accept-encoding</code>
<code>content-type: text/html</code>
apache 配置了 “event mpm”。
<code>server: nginx/1.10.1</code>
<code>date: sun, 30 oct 2016 14:17:30 gmt</code>
<code>connection: keep-alive</code>
<code>keep-alive: timeout=20</code>
<code>etag: "58160010-2cf2"</code>
nginx 包括幾個調整:<code>sendfile on</code>、<code>tcp_nopush on</code> 和 <code>tcp_nodelay on</code>。
<code>$: curl -i http://127.0.0.1:8080</code>
<code>etag: 15</code>
<code>last-modified: thu, 27 oct 2016 14:09:58 gmt</code>
<code>date: sun, 30 oct 2016 16:39:47 gmt</code>
在靜态測試中使用的 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 之間還有一個顯著的性能落差,後者更佳,我将在下面簡要介紹一下,可能會出現一些與初衷大相徑庭的結果。
為了比較 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 是一個完全成熟的 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 的力量來達到更好的性能。
原文釋出時間為:2017-11-30
本文來自雲栖社群合作夥伴“linux中國”