目前,Web緩存服務器的應用模式主要是正向代理和反向代理。正向代理(Proxy)模式是代理網絡用戶訪問internet,客戶端將原本要直接發送到internet上源服務器的鏈接請求發送給代理服務器處理。正向代理的目的是加速用戶在使用瀏覽器訪問Internet時的請求響應時間,並提升廣域網線路的利用率。正向代理瀏覽器無需和該站點創建聯繫,只訪問到Web緩存便可。經過正向代理,大大提升了後續用戶的訪問速度,使他們無需再穿越Internet,只要從本地Web緩存就能夠獲取所須要的信息,避免了帶寬問題,同時能夠大量減小重複請求在網絡上的傳輸,從而下降網絡流量,節省資費。php
反向代理(Reverse Proxy)模式是針對Web服務器加速功能的,在該模式中,緩存服務器放置在web應用服務器的前面,當用戶訪問web應用服務器的時候,首先通過緩存服務器,並將用戶的請求和應用服務器應答的內容寫入緩存服務器中,從而爲後續用戶的訪問提供更快的響應。html
Squid是一種用來緩衝Internet數據的軟件。它是這樣實現其功能的,接受來自人們須要下載的目標(object)的請求並適當地處理這些請求。也就是說,若是一我的想下載一web頁面,他請求Squid爲他取得這個頁面。Squid隨之鏈接到遠程服務器(好比:http://squid.nlanr.net/)並向這個頁面發出請求。而後,Squid顯式地彙集數據到客戶端機器,並且同時複製一份。當下一次有人須要同一頁面時,Squid能夠簡單地從磁盤中讀到它,那樣數據迅即就會傳輸到客戶機上。當前的Squid能夠處理HTTP,FTP,GOPHER,SSL和WAIS等協議。但它不能處理如POP,NNTP,RealAudio以及其它類型的東西。linux
Squid可以實現的功能:nginx
a. 標準的代理緩衝服務器c++
一個標準的代理緩衝服務被用於緩存靜態的網頁(例如:html文件和圖片文件等)到本地網絡上的一臺主機上(即代理服務器)。當被緩存的頁面被第二次訪問的時候,瀏覽器將直接從本地代理服務器那裏獲取請求數據而再也不向原web站點請求數據。這樣就節省了寶貴的網絡帶寬,並且提升了訪問速度。可是,要想實現這種方式,必須在每個內部主機的瀏覽器上明確指明代理服務器的IP地址和端口號。客戶端上網時,每次都把請求送給代理服務器處理,代理服務器根據請求肯定是否鏈接到遠程web服務器獲取數據。若是在本地緩衝區有目標文件,則直接將文件傳給用戶便可。若是沒有的話則先取回文件,先在本地保存一份緩衝,而後將文件發給客戶端瀏覽器。web
b. 透明代理緩衝服務器正則表達式
透明代理緩衝服務和標準代理服務器的功能徹底相同。可是,代理操做對客戶端的瀏覽器是透明的(即不需指明代理服務器的IP和端口)。透明代理服務器阻斷網絡通訊,而且過濾出訪問外部的HTTP(80端口)流量。若是客戶端的請求在本地有緩衝則將緩衝的數據直接發給用戶,若是在本地沒有緩衝則向遠程web服務器發出請求,其他操做和標準的代理服務器徹底相同。對於Linux操做系統來講,透明代理使用Iptables或者Ipchains實現。由於不須要對瀏覽器做任何設置,因此,透明代理對於ISP(Internet服務器提供商)特別有用。算法
c. 反向代理緩衝服務器chrome
反向代理是和前兩種代理徹底不一樣的一種代理服務。使用它能夠下降原始WEB服務器的負載。反向代理服務器承擔了對原始WEB服務器的靜態頁面的請求,防止原始服務器過載。它位於本地WEB服務器和Internet之間,處理全部對WEB服務器的請求,組織了WEB服務器和Internet的直接通訊。若是互聯網用戶請求的頁面在代理服務器上有緩衝的話,代理服務器直接將緩衝內容發送給用戶。若是沒有緩衝則先向WEB服務器發出請求,取回數據,本地緩存後再發送給用戶。這種方式經過下降了向WEB服務器的請求數從而下降了WEB服務器的負載。數據庫
Nginx ("engine x") 是一個高性能的 HTTP 和 反向代理 服務器,也是一個 IMAP/POP3/SMTP 服務器。 Nginx 是由 Igor Sysoev 爲俄羅斯訪問量第二的 Rambler.ru 站點開發的,第一個公開版本0.1.0發佈於2004年10月4日。其將源代碼以類BSD許可證的形式發佈,因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名。2011年6月1日,nginx 1.0.4發佈。
Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。由俄羅斯的程序設計師Igor Sysoev所開發,供俄國大型的入口網站及搜索引擎Rambler(俄文:Рамблер)使用。其特色是佔有內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、新浪、網易、騰訊等。
Nginx隨具備緩存功能,可是對於緩存這一功能來講並非專業的,他的主要用途仍是做爲web服務器來使用。
Varnish 是一款高性能且開源的反向代理服務器和 HTTP 加速器,其採用全新的軟件體系機構,和如今的硬件體系緊密配合,與傳統的 squid 相比,varnish 具備性能更高、速度更快、管理更加方便等諸多優勢,不少大型的網站都開始嘗試使用 varnish 來替換 squid,這些都促進 varnish 迅速發展起來。挪威的最大的在線報紙 Verdens Gang(vg.no) 使用 3 臺 Varnish 代替了原來的 12 臺 Squid,性能比之前更好,這是 Varnish 最成功的應用案例。
varnish自己的技術上優點要高於squid,它採用了「Visual Page Cache」技術,在內存的利用上,Varnish比Squid具備優點,它避免了Squid頻繁在內存、磁盤中交換文件,性能要比Squid高。 varnish是不能cache到本地硬盤上的。還有強大的經過Varnish管理端口,可使用正則表達式快速、批量地清除部分緩存。
Varnish 與通常服務器軟件相似,分爲 master 進程和 child 進程。Master 進程讀入存儲配置文件,調用合適的存儲類型,而後建立 / 讀入相應大小的緩存文件,接着 master 初始化管理該存儲空間的結構體,而後 fork 並監控 child 進程。Child 進程在主線程的初始化的過程當中,將前面打開的存儲文件整個 mmap 到內存中,此時建立並初始化空閒結構體,掛到存儲管理結構體,以待分配。Child 進程分配若干線程進行工做,主要包括一些管理線程和不少 worker 線程。
varnish 的某個負責接收新 HTTP 鏈接線程開始等待用戶,若是有新的 HTTP 鏈接過來,它總負責接收,而後喚醒某個等待中的線程,並把具體的處理過程交給它。Worker 線程讀入 HTTP 請求的 URI,查找已有的 object,若是命中則直接返回並回複用戶。若是沒有命中,則須要將所請求的內容,從後端服務器中取過來,存到緩存中,而後再回復。
分配緩存的過程是這樣的:它根據所讀到 object 的大小,建立相應大小的緩存文件。爲了讀寫方便,程序會把每一個 object 的大小變爲最接近其大小的內存頁面倍數。而後從現有的空閒存儲結構體中查找,找到最合適的大小的空閒存儲塊,分配給它。若是空閒塊沒有用完,就把多餘的內存另外組成一個空閒存儲塊,掛到管理結構體上。若是緩存已滿,就根據 LRU 機制,把最舊的 object 釋放掉。
釋放緩存的過程是這樣的:有一個超時線程,檢測緩存中全部 object 的生存期,若是超初設定的 TTL(Time To Live)沒有被訪問,就刪除之,而且釋放相應的結構體及存儲內存。注意釋放時會檢查該存儲內存塊前面或後面的空閒內存塊,若是前面或後面的空閒內存和該釋放內存是連續的,就將它們合併成更大一塊內存。
整個文件緩存的管理,沒有考慮文件與內存的關係,其實是將全部的 object 都考慮是在內存中,若是系統內存不足,系統會自動將其換到 swap 空間,而不須要 varnish 程序去控制。
1、測試環境
1,硬件是奔騰雙核,機子三年前買的。系統是archlinux
2,測試varnish和squid的時候,web服務用的apache
3,測試nginx的時候,啓動了十個nginx進程,20個php-cgi進程
4,varnish,squid,nginx用的是反向代理的形勢,也就是說訪問圖片的時候,要先透過緩存工具
二,測試
1,varnish
[root@BlackGhost bin]# /usr/local/bin/webbench -c 100 -t 20 http://127.0.0.1:8080/00/01/RwGowEtWvcQAAAAAAAAWHH0Rklg81.gif
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://127.0.0.1:8080/00/01/RwGowEtWvcQAAAAAAAAWHH0Rklg81.gif
100 clients, running 20 sec.
Speed=476508 pages/min, 47258114 bytes/sec.
Requests: 158836 susceed, 0 failed.
2,squid
[root@BlackGhost bin]# /usr/local/bin/webbench -c 100 -t 20 http://localhost:9000/00/01/RwGowEtWvcQAAAAAAAAWHH0Rklg81.gif
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://localhost:9000/00/01/RwGowEtWvcQAAAAAAAAWHH0Rklg81.gif
100 clients, running 20 sec.
Speed=133794 pages/min, 7475018 bytes/sec.
Requests: 44598 susceed, 0 failed.
3,nginx
[root@BlackGhost conf]# /usr/local/bin/webbench -c 100 -t 20 http://localhost:10000/00/01/RwGowEtWvcQAAAAAAAAWHH0Rklg81.gif
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://localhost:10000/00/01/RwGowEtWvcQAAAAAAAAWHH0Rklg81.gif
100 clients, running 20 sec.
Speed=304053 pages/min, 30121517 bytes/sec.
Requests: 101351 susceed, 0 failed.
從這些功能上看varnish和squid是專業的cache服務,而nginx等這些都是第三方模塊完成。要作cache服務的話,咱們確定是要選擇專業的cache服務,優先選擇squid和varnish。通過對以上最流行的三中緩存服務進行對比發現,Varnish是實現頁面緩存的最佳方案。(請參照3.1性能對比)
*來源網絡,實際配置安裝手冊正在完善
建議下載最新穩定版本(如今最新 varnish 版本爲 3.0.2),varnish 提供源代碼安裝包和可執行程序安裝包,按照您的習慣下載適合您平臺的任一安裝包便可。
源代碼安裝包安裝
首先安裝 pcre 庫,pcre 庫是爲兼容正則表達式,若是不安裝,在安裝 varnish2.0 版本以上時,會提示找不到 pcre 庫。如下是 pcre 的安裝過程,其代碼如清單 1 所示:
tar zxvf pcre.tar.gz
cd pcre/
./configure --prefix=/usr/local/pcre/
Make && make install
安裝 varnish,其代碼如清單 2 所示:
tar xzvf varnish-3.0.2.tar.gz
cd varnish-3.0.2
export PKG_CONFIG_PATH =/usr/local/pcre/lib/pkgconfig
./configure --prefix=/usr/local/varnish
make
make install
可執行程序安裝包安裝
RedHat 系統環境下的安裝 varnish,您須要安裝如下軟件:automake、autoconf、libtool、ncurses-devel、libxslt、groff、pcre-devel、pkgconfig,而後進行 varnish 的安裝,安裝代碼如清單 3 所示:
rpm -i varnish-2.1.4-2.el5.x86_64.rpm
清單 4. varnish 啓動代碼
varnishd -f /etc/varnish/default.vcl -s file,/var/varnish_cache,1G \
-T 127.0.0.1:2000 -a 0.0.0.0:9082
各參數的含義以下:
-f 指定 varnish 的配置文件位置
-s 指定 varnish 緩存存放的方式,經常使用的方式有:「-s file,<dir_or_file>,<size>」。
-T address:port 設定 varnish 的 telnet 管理地址及其端口
-a address:port 表示 varnish 對 http 的監聽地址及其端口
VCL(varnish configuration language)是 varnish 配置語言,其用來定義 varnish 的存取策略。VCL 語法比較簡單,跟 C 和 Perl 比較類似。主要有如下幾點:
set req.http.X-hit = " hit" "it";
聲明並初始化一個後端對象,代碼如清單 6 所示
backend www {
.host = "www.example.com";
.port = "9082";
}
後端對象的使用,代碼如清單 7 所示
if (req.http.host ~ "^(www.)?example.com$") {
set req.backend = www;
}
VCL 能夠把多個 backends 聚合成一個組,這些組被叫作 director,這樣能夠加強性能和彈力,當組裏一個 backend 掛掉後,能夠選擇另外一個健康的 backend。VCL 有多種 director,不一樣的 director 採用不一樣的算法選擇 backend,主要有如下幾種:
Random director 會根據所設置的權值(weight)來選擇 backend,.retries 參數表示嘗試找到一個 backend 的最大次數,.weight 參數表示權值
Round-robin director 在選擇 backend 時,會採用循環的方式依次選擇。
Client director 根據 client.identity 來選擇 backend,您能夠設置 client.identity 的值爲 session cookie 來標識 backend。
VCL 能夠設置 probe 來檢測一個 backend 是否健康,定義一個 backend probes 代碼如清單 8 所示:
backend www {
.host = "www.example.com";
.port = "9082";
.probe = {
.url = "/test.jpg";// 哪一個 url 須要 varnish 請求
.timeout = 1 s;// 等待多長時間超時
.interval = 5s// 檢查的時間間隔
.window = 5;// 維持 5 個 sliding window 的結果
.threshold = 3;// 至少有三次 window 是成功的,就宣告 backend 健康
}
}
ACL 可建立一個客戶端的訪問控制列表,你可使用 ACL 控制哪些客戶端能夠訪問,哪些客戶端禁止訪問。定義 ACL 代碼如清單 9 所示:
Acl local{
"localhost";
"192.0.2.0"/24;
!"192.0.2.23";// 除去該 IP
}
vcl_recv 函數
用於接收和處理請求。當請求到達併成功接收後被調用,經過判斷請求的數據來決定如何處理請求。例如如何響應、怎麼響應、使用哪一個後端服務器等。
此函數通常以以下幾個關鍵字結束。
pass:表示進入 pass 模式,把請求控制權交給 vcl_pass 函數。
pipe:表示進入 pipe 模式,把請求控制權交給 vcl_pipe 函數。
lookup:表示進入 lookup 模式,把請求控制權交給 lookup 指令處理,在緩存中查找被請求的對象,而且根據查找的結果把控制權交給函數 vcl_hit 或函數 vcl_miss。
error code [reason]:表示返回「code」給客戶端,並放棄處理該請求。「code」是錯誤標識,例如 200 和 405 等。「reason」是錯誤提示信息。
vcl_pipe 函數
此函數在進入 pipe 模式時被調用,用於將請求直接傳遞至後端主機,在請求和返回的內容沒有改變的狀況下,將不變的內容返回給客戶端,直到這個鏈接被關閉。
此函數通常以以下幾個關鍵字結束。
error code [reason]。
pipe。
vcl_pass 函數
此函數在進入 pass 模式時被調用,用於將請求直接傳遞至後端主機。後端主機在應答數據後將應答數據發送給客戶端,但不進行任何緩存,在當前鏈接下每次都返回最新的內容。
此函數通常以以下幾個關鍵字結束。
error code [reason]。
pass。
restart 從新啓動流程,增長啓動次數,若是從新啓動次數高於 max_restarts 發出一個錯誤警告
vcl_hash
當您想把一個數據添加到 hash 上時,調用此函數。
此函數通常以以下幾個關鍵字結束。
Hash。
vcl_hit 函數
在執行 lookup 指令後,在緩存中找到請求的內容後將自動調用該函數。
此函數通常以以下幾個關鍵字結束。
deliver:表示將找到的內容發送給客戶端,並把控制權交給函數 vcl_deliver。
error code [reason] 。
pass。
restart 從新啓動流程,增長啓動次數,若是從新啓動次數高於 max_restarts 發出一個錯誤警告
vcl_miss 函數
在執行 lookup 指令後,在緩存中沒有找到請求的內容時自動調用該方法。此函數可用於判斷是否須要從後端服務器獲取內容。
此函數通常以以下幾個關鍵字結束。
fetch:表示從後端獲取請求的內容,並把控制權交給 vcl_fetch 函數。
error code [reason] 。
pass。
vcl_fetch 函數
在後端主機更新緩存而且獲取內容後調用該方法,接着,經過判斷獲取的內容來決定是將內容放入緩存,仍是直接返回給客戶端。
此函數通常以以下幾個關鍵字結束。
error code [reason]。
pass。
deliver。
esi。
restart 從新啓動流程,增長啓動次數,若是從新啓動次數高於 max_restarts 發出一個錯誤警告
vcl_deliver 函數
將在緩存中找到請求的內容發送給客戶端前調用此方法。
此函數通常以以下幾個關鍵字結束。
error code [reason]。
deliver。
restart 從新啓動流程,增長啓動次數,若是從新啓動次數高於 max_restarts 發出一個錯誤警告
vcl_error
出現錯誤時調用此函數。
此函數通常以以下幾個關鍵字結束。
deliver。
restart。
VCL 處理的流程圖如圖 1 所示
Varnish 處理 HTTP 請求的過程大體分爲以下幾個步驟。
VCL 內置的公共變量能夠用在不一樣的 VCL 函數中,下面根據使用的不一樣階段進行介紹
當請求到達時,可使用的公共變量表 1 所示
公共變量名 |
含義 |
req.backend |
指定對應的後端主機 |
server.ip |
表示服務器 IP |
client.ip |
表示客戶端 IP |
req.quest |
只是請求的類型,例如 GET、HEAD 等 |
req.url |
指定請求的地址 |
req.proto |
表示客戶端發起請求的 HTTP 協議版本 |
req.http.header |
表示對應請求中的 HTTP 頭部信息 |
req.restarts |
表示重啓次數,默認最大值爲 4 |
Varnish 在向後端主機請求時,但是用的公共變量如表 2 所示
公共變量名 |
含義 |
beresp.requset |
指定請求類型,例如 GET、HEAD 等 |
beresp.url |
表示請求地址 |
beresp.proto |
表示客戶端發起請求的 HTTP 協議版本 |
beresp.http.header |
表示對應請求中 HTTP 頭部信息 |
beresp.ttl |
表示緩存的生存週期,cache 保留時間(s) |
從 cache 或是後端主機獲取內容後,可使用的公共變量如表 3 所示
公共變量名 |
含義 |
obj.status |
返回內容的請求狀態碼,例如 200、30二、504 等 |
obj.cacheable |
返回的內容是否能夠緩存 |
obj.valid |
是否有效的 HTTP 請求 |
obj.response |
返回內容的請求狀態信息 |
obj.proto |
返回內容的 HTTP 版本 |
obj.ttl |
返回內容的生存週期,也就是緩存時間,單位秒 |
obj.lastuse |
返回上一次請求到如今的時間間隔,單位秒 |
對客戶端應答時,可使用的公共變量如表 4 所示
公共變量名稱 |
含義 |
resp.status |
返回給客戶端的 HTTP 代碼狀態 |
resp.proto |
返回給客戶端的 HTTP 協議版本 |
resp.http.header |
返回給客戶端的 HTTP 頭部消息 |
resp.response |
返回給客戶端的 HTTP 頭部狀態 |
VCL 爲配置文件語言,沒法像 c/c++ 那樣進行單步調試,當 VCL 運行的效果和預期效果不同時,很難發現哪出現邏輯錯誤,這時除了查看代碼查找錯誤外,咱們還能夠採用內置 C 語言和瀏覽器查看返回對象中的狀態來查找邏輯的錯誤。
咱們能夠採用內置 C 語言來打印相應的信息,例如咱們能夠在相應的地方打印信息,來查看 VCL 流程的執行是否正確。內置 C 語言打印信息代碼如清單 10 所示:
C{
#include<syslog.h>// 首先要包含頭文件
}C
C{
Syslog(LOG_INFO,"VCL run here in function xxx in line xxx");
}C
啓動 varnish 後,咱們能夠採用 tail -f /var/log/messages 命令在 /var/log/messages 中查看相應的打印信息。查看的打印信息如圖 2 所示:
咱們還能夠將某些變量的值設置到返回給瀏覽器的對象上,而後在瀏覽器中查看該變量的值。設置變量值代碼如清單 11 所示:
set beresp.http.X-Cookie-Debug-req-cookie = req.http.Cookie;
在 chrome 瀏覽器中查看 beresp.http.X-Cookie-Debug-req-cookie 的值,結果如圖 3 所示:
Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,可是客戶端能夠用任何語言來編寫,並經過memcached協議與守護進程通訊。
memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 爲首開發的一款軟件。已成爲mixi、hatena、Facebook、Vox、LiveJournal等衆多服務中提升Web應用擴展性的重要因素。許多Web應用都將數據保存到RDBMS中,應用服務器從中讀取數據並在瀏覽器中顯示。但隨着數據量的增大、訪問的集中,就會出現RDBMS的負擔加劇、數據庫響應惡化、網站顯示延遲等重大影響。
memcached是高性能的分佈式內存緩存服務器。通常的使用目的是,經過緩存數據庫查詢結果,減小數據庫訪問次數,以提升動態Web應用的速度、提升可擴展性。Memcached 的守護進程(daemon )是用C寫的,可是客戶端能夠用任何語言來編寫,並經過memcached協議與守護進程通訊。可是它並不提供冗餘(例如,複製其hashmap條目);當某個服務器S中止運行或崩潰了,全部存放在S上的鍵/值對都將丟失。
Memcached由Danga Interactive開發,其最新版本發佈於2010年,做者爲Anatoly Vorobey和Brad Fitzpatrick。用於提高LiveJournal . com訪問速度的。LJ每秒動態頁面訪問量幾千次,用戶700萬。Memcached將數據庫負載大幅度下降,更好的分配資源,更快速訪問。