想象一下,你剛剛發布了一篇博文,并分享到了社交網絡。然后,這篇文章恰巧被大V看中再次分享了出去,立即吸引了數百粉絲的目光,引導他們涌入了你的網站。看到這么多的訪客量,以及它們的評論,你內心激動不已。突然之間,你的網站就掛掉了,滿屏的數據連接錯誤……
或者假想另一種情境,你一直很努力地創業。突然有一天,一個大V在社交網絡表達了對貴公司的喜愛之情,字里行間滿滿的贊嘆。關注這個大V的粉絲心動了,又涌入了你的網站。不幸的是,點擊連接后卻無法進入你的網站,或者進入后無法注冊用戶,甚至頁面相應超時,無法獲取產品的序列號。盡管你在社交網絡上對此非常誠懇的表達了歉意,但眾多的瀏覽者都不會再有興趣。
這些假想其實非常普遍。在我的工作中,就經常發現,當網站信息在社交網站流傳開來的時候,移動設備的訪問請求就會驟增。這也表明,在社交網絡中,越來越多的人開始使用移動設備,而不是傳統的桌面應用。此外,大多數的移動用戶都在使用公共 Wi-Fi 以及其他低速網絡來訪問網站。所以,快速加載網站的任何優化措施,都會有利于用戶的訪問。
在本文中,我會向你介紹 Varnish 網頁應用加速器(Varnish Web application accelerator)——這是一個免費、簡單的工具,大大改善大規模突發性訪問狀態下的響應能力。
亮點
對于大多數的網站來說,眾多用戶請求訪問的核心內容大都是一致的——尤其是每天都會更新內容的門戶網站。不用多說你也會理解,圖片、CSS 和 JavaScript,這些靜態資源往往有較長的有效期(譯者注:有利于在不同頁面間復用)。但你可能沒有深入思考過,通常在博客平臺或者是內容管理系統中,響應用戶的請求后,所返回的數據內容,大多也是相同的。
來自社交網絡的用戶進入一個博客后,并不會請求完全一致的信息。除了圖片、JavaScript 和 CSS,這些信息還包括 PHP 動態生成的內容,以及從數據庫查詢到的數據。訪問博客中的某一篇博文,所需要發送的每一條請求,不僅僅是在獲取網絡服務器提供的靜態資源,還需要配合 PHP 腳本,使用數據庫連接以及數據庫表單檢索等功能。
數據庫連接的數量越多,Apache 需要處理的進程就會越多,而總的處理能力是由限度的。相應的,訪客的數量越多,服務就會越不穩定,掙到的錢就會越少。
這就是類似 Varnish 的 HTTP 緩存發揮作用的地方。如此一來,從瀏覽器發出的請求,不再直接到達創建和維護網頁的服務器,而是到達 HTTP 緩存服務器。如果緩存服務器中存在所需頁面,那么直接從服務器的內存返回相應的資源,不再動用 Apache 服務器和數據庫。如果所需頁面不再緩存中,那么就像傳統方式一樣,使用 Apache 服務器來處理。Apche 處理完成之后,就會將這個頁面保存到 HTTP 緩存服務器中,等到下一次請求相同頁面時就可以直接返回了。
將頁面保存在內存中,其響應速度遠快于將其保存在硬盤中。此外,當請求的頁面為于 HTTP 緩存服務器中時,就無需動用 PHP 或者數據庫來處理相關操作。這也讓 PHP 和 服務器能夠有更多的性能來處理更繁重的進程和連接。比如,上面提到的被大 V 稱贊的那家初創公司面臨的情境,眾多粉絲點擊的鏈接其實只是網站中的少數幾個頁面——而這些完全可以保存在高速緩存服務器中,當需要時直接從內存響應請求。此時,準備注冊的用戶就會感到整個流程非常順利,因為后臺腳本和數據庫連接的處理能力非常寬裕,完全不受突發性請求的影響。
原理
下面這個示意圖,展示了 Apache 服務器響應請求后生成站點內容的基本流程。在這個例子中,為了請求相同的頁面,一共從瀏覽器發送了五條指令給 Apache,而 Apache 很呆板的對每條請求都做了詳細的處理。
是的,Apache 處理了每一條請求——圖像,CSS,JavaScript 和 HTML 文件。如果 PHP 中有某個文件,就會解析一次。如果需要請求數據庫的信息,那么就要執行一次數據連接,進行 SQL 查詢等操作。最終,在 Apache 返回給瀏覽器信息之前,數據庫返回相關信息組裝成完成的頁面。
如果我們在 Apache 之間使用 Varnish,我們就可以形成這樣的一個流程:
如果瀏覽器請求的資源和頁面已經存在緩存中,那么 Varnish 就會直接從內存返回這些資源,而 Apache、PHP 和 MySql 完全不需要進行重復的操作。如果瀏覽器請求的數據不再緩存中,那么 Varnish 就會將相關的處理工作轉移給 Apache,讓 Apache 處理相關的細節。這種方式的優勢就在于,只讓 Apache 處理必要的工作,一旦生成了所需的資源,該資源就會被保存到緩存服務器的內存中。當再次有請求訪問這些資源時,Varnish 就完全有能力應付了。
這個工具還有另一項好處。在 Varnish 的屬于中,你所配置的 Apache 服務器,被稱為“處理后臺”。Varnish 允許配置多個處理后臺。所以,你可以同時運行兩個網絡服務器,比如,一臺使用 Apache 處理 PHP 頁面,一臺使用 nginx 處理靜態資源。在 Varnish 中設置成功后,就可以從正確的服務器獲取相應的資源。在本篇教程中,我們將著眼于一個簡單的示例。
震驚!快教我吧
安裝和配置 Varnish 相當簡單。你需要獲得服務器的 root 權限(sudo),才能安裝 Varnish。因此,你的網站需要托管在類似 VPS 的服務器上。現在 VPS 的價格也不是那么昂貴了,而且使用 Varnish 也會影響大家選擇 VPS 而不是共享服務器。
有些 CMS 擁有的插件,可以直接使用 Varnish,或者將其整合進控制面板——通常可以更輕松地清空緩存。當然,你可以將 Varnish 融入任何的 CMS 或者靜態網站中,而不需要特殊的配置。
在演示安裝 Varnish 的整個流程之前,我會假設你已經在系統中使用 Apache 作為服務器了。雖然我在使用 Debian Linux,但安裝過程中用到的軟件包對其他分發版本也是適用的(只是系統中的文件路徑會有所不同)。
在開始之前,先檢查一下網站是否正常運行在 Apache 上。如果你使用的服務器是個新品,或者你想在本地虛擬機上嘗試 Varnish,那么請確保配置一個虛擬主機,并可以用瀏覽器打開這個服務器的測試頁面。
安裝 Varnish
各個平臺的詳細安裝說明請參考 Varnish 官方文檔。因為我使用的是 Debian Wheezy,所以我會遵循 Debian 部分的說明。一旦 Varnish 安裝完成,終端中就會輸出下面這段話,提示你安裝成功了:
Apache 默認監聽來自 80 端口的請求。這個端口接收請求,所以為了配合 Varnish 置于 Apache 之前的布局,需要修改端口,讓 Varnish 監聽 80 端口,同時將 Apache 的端口修改為一個與之不同的值——一般來說是 8080。然后在 Varnish 中配置相關信息,讓 Varnish 連通 Apache。
重新配置 Apache
為了修改 Apache 當前的監聽端口,需要使用 root 權限打開 /etc/apache2/ports.conf 文件,找到下面這兩行:
Listen 80
修改為:
Listen 8080
如果看到了下面這兩行,只需要修改 80 為 8080 即可:
Listen 80
然后保存該文件并打開默認的虛擬主機文件,該文件應該在 /etc/apache2/sites-available。在這個文件中,找到下面這一行:
修改為:
當然,你也需要修改其他用到的虛擬主機。
配置 Varnish
打開 /etc/default/varnish 文件,將頁面滾動到沒有注釋、以 DAEMON_OPTS 開頭的部分。將這一部分編輯如下,使 Varnish 監聽 80 端口:
-T localhost:1234
-f /etc/varnish/default.vcl
-S /etc/varnish/secret
-s malloc,256m"
打開 /etc/varnish/default.vcl 文件,檢查默認的后臺端口并設置為 8080,用來連通 Apache :
.host = "127.0.0.1";
.port = "8080";
}
在 root 權限下,使用如下命令重啟 Apache 和 Varnish:
service varnish restart
檢查先前的測試頁面是否仍然可以連接。如果可以,那么你可能想知道如何測試網站是否已經被緩存到了 Varnish 上。事實上有好幾種方式,最簡單的是使用 cURL。請在命令行中輸入以下命令:
此時獲得響應應該類似于 Via: 1.1 varnish。
你也可以查看由 Varnish 生成的靜態資源。在終端中,輸入 varnishstat,然后在瀏覽器中刷新頁面,就會看到點擊率逐漸增加。如果是由 Varnish 提供的資源,那么會標識為 hit;如果由 Apache 或其他后臺提供,標識為 miss。
另一個有用的工具是 varnish-top。首先在命令行中輸入 varnishtop -i txurl,然后在瀏覽器中刷新頁面。這個工具將會顯示哪些頁面是由 Varnish 提供的。
清除緩存
當頁面被緩存之后,當你改動 HTML 或者 CSS 文件,并不會立即看到更新的部分。這經常讓我出差錯。雖然我知道在 Apache 之前有個緩存服務器,但還是經常會犯傻“剛剛我的修改哪去了?”在命令行輸入 varnishadm "ban.url ." 即可清除全部的緩存。
你也可以通過 HTTP 控制 Varnish。這方面有很多插件,比如服務于 WordPress 的 Varnish HTTP Purge,可以直接通過管理界面清除緩存。
自定義
也許,你會想通過了解一些 Varnish 的工作原理來微調它的配置。如果按照上述步驟配置 Varnish,一旦靜態資源和頁面被緩存到內存中,會逐漸積累起大量的靜態資源和頁面。
Varnish 只會緩存那些不會影響安全的資源,也因此有時不會緩存一些你認為會被緩存的資源,比如,cookies。
在默認配置中,如果設置了 cookie,那么 Varnish 就不會緩存相應的內容。所以,如果你的站點為不同用戶提供不同的內容,比如個人資料,那么你肯定不會為了一個用戶緩存所有人的資料。不過,有時你又會希望忽略一些 cookies,比如為了某些分析工作。如果網站并不提供任何個人資料,那么唯一需要考慮 cookies 的地方就是后臺管理部分——如果 Varnish 緩存了后臺管理的部分,那么查看修改就會非常不方便。
讓我們修改一下 /etc/varnish/default.vcl 文件。假設你的后臺管理部分在 /admin,那么你需要添加如下內容:
if ( !( req.url ~ ^/admin/) ) {
unset req.http.Cookie;
}
}
有些 cookies 可能非常重要,比如已經登錄的用戶 cookies 就不應該緩存。所以,你就不會希望排除所有的 cookies。此處使用一個正則表達式可以定義那些 cookies 是我們需要的。也可以下哦那個網上找到很多解決這個問題的方案。對于分析工具的 cookies,你可以添加如下內容:
// Remove has_js and Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;s*)(_[_a-z]+|has_js)=[^;]*", "");
// Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;s*", "");
}
Varnish 文檔中有一個專門的部分講解 cookies。
在大多數情境下,按照上述配置 Varnish,并移除分析工具的 cookies,將會大大加快網站的訪問速度。一旦 Varnish 建立并運行起來,在熟悉了配置的基礎上,你就可以微調配置,從緩存規則中獲得最佳性能。
進階
更多資料,請參考 Varnish 官方文檔。你應該從現在起嘗試一些操作實例,深入了解 Varnish 的基礎知識。