對於片斷緩存,業界有成熟的解決方案,還有一個所謂的W3C標準:ESI(Edge Side Include) 。html
ESI自己沒有什麼,只是一個XML的標籤集合。ESI和SSI(Server Side Include)很類似,作過ASP開發的都熟悉這麼一個標籤:前端
<!--#include src="header.inc" -->
IIS碰到這麼一個標籤後,會把header.inc裏面的東西合併到當前的頁面,這樣作的好處是header.inc自己能夠複用了,你能夠在多個頁面include它。web
ESI的功能也是相似的,只不過解析和合並它的任務通常落到緩存服務器或代理上:數據庫
1: <esi:include src="/welcome" />
2: <ul>
3: #foreach($book in $books)
4: <li>$book.name</li>
5: #end
6: </ul>
好比對於上面這個片斷,esi:include標籤那裏原本是應該顯示特定於每一個用戶的歡迎信息的,就由於這一點整個頁面不能緩存太惋惜了。這個時候ESI粉墨登場。緩存服務器會將整個頁面cache,而後它發現這兒有個ESI標籤,它會根據src指定的地址去源服務器請求內容,而後將其合併到緩存的頁面中,而後將完整的內容發送到客戶端。整個過程相似下圖所示:後端
這樣咱們就不須要每次都去數據庫查詢那個圖書列表了,由於圖書列表可能更新的很緩慢。這樣大大的下降了Web服務器的壓力。瀏覽器
既然ESI是一個規範,那麼確定有遵循這個規範的實現。好比大名鼎鼎的Squid就有支持ESI的模塊。不過本文要介紹的是Varnish。Varnish是一個反向代理,使用緩存對HTTP加速,能夠把它放到你的Web服務器的前面,對內容緩存,跟Squid的目的類似。不過由於Squid想幹的事兒實在是太多,它已經再也不是一個純粹的用戶緩存加速的方向代理了,因此顯得太過於臃腫,而比較起來Varnish更專一,更輕便。根據網站上的數據顯示,Varnish表現出來的性能比Squid更好,並且佔用的資源更少。緩存
下面我就簡單的描述一下如何安裝Varnish以及配置使用ESI。服務器
我是在Mac上安裝Varnish的,從源代碼編譯過去的。基本上是一路命令下去,在configure的時候碰到缺乏libpcre,用port裝上pcre就能夠了:架構
1: $wget http://repo.varnish-cache.org/source/varnish-2.1.5.tar.gz
2: $tar zxvf varnish-2.1.5.tar.gz
3: $cd varnish-2.1.5
4: $sh autogen.sh
5: $sh configure
6: $make
7: $make install
根據環境不一樣,可能缺乏一些依賴,我在安裝的過程當中就缺乏libpcre。app
Varnish默認是安裝在/usr/local/sbin目錄下:varnishd。是daemo。
根據上面那幅圖能夠看出,Varnish並不本身提供服務,它只是做爲一個緩存服務器。那麼就必須有一個後端的服務器提供應用程序的服務。那咱們就須要讓Varnish知道到哪兒去請求後端服務器。這個是經過配置文件設置的,Varnish的默認配置文件在/usr/local/etc/varish/default.vcl。
打開後咱們會發現一段被註釋的代碼,取消註釋將其指向你的後端服務器(好比IIS):
1: backend default {
2: .host = "127.0.0.1";
3: .port = "8080";
4: }
配置好後,啓動Varnish,而後去看看效果,啓動的命令是:
1: sbin yuyi$sudo ./varnishd -a 0.0.0.0:80 -f /usr/local/etc/varnish/default.vcl -s malloc,500M
我簡單的介紹下這幾個選項,更詳細的能夠看man。
-a指定Varnish鑑定的地址。若是你的配置是上圖所示,那麼端口應該是80。若是你沒有指定-a,那麼默認配置使用/etc/services中的配置,通常狀況下就是80。而-f指定配置文件的地址,默認狀況下就是default.vcl,除非你想使用別的配置文件。
最有趣的是-s選項,它用來指定存儲方式,以及緩存的大小。好比這裏是malloc,那就是使用內存做爲緩存,你還可使用file,使用磁盤做爲緩存。後面是緩存大小,500兆。還能夠指定K,G,T等,大小寫均可以。
運行後咱們去瀏覽器打開http://127.0.0.1看看。爲了測試你能夠在頁面輸出一個DateTime.Now,而後刷新頁面看看是否是每次都變化。
Varnish還有個不錯的工具:varnishlog,打開後能夠看到用戶訪問的一些狀況。
好了,安裝和簡單配置就介紹這麼多,那如何使用ESI呢?其實很簡單,分爲兩個步驟,首先將你的頁面上須要施加不一樣緩存策略的片斷切分,放到不一樣的鏈接中。
好比原來你的首頁混沌一片:有熱點新聞板塊、通知板塊、還有廣告以及顯示用戶登陸的板塊。而它們原來極可能都是由index.aspx處理的。若是你想有針對性的對這些板塊施加緩存策略,那麼就應該將其獨立開,使用不一樣的鏈接(控制器)來處理:
1: <html>
2: <head>
3: <title>index</title>
4: </head>
5: <body>
6: <p>Welcome yuyijq</p>
7: <div>
8: <h3>Hot News</h3>
9: <ul>
10: <li>慶祝奧特曼45歲生日</li>
11: <li>拉登掛了</li>
12: </ul>
13: </div>
14: <div>
15: <h3>通知</3>
16: <ul>
17: <li>機房維護通知</li>
18: </ul>
19: </div>
20: </body>
21: <html>
如今咱們要拆分: hotnews->hotnews.aspx welcome->welcome.aspx
而後使用ESI標籤分離:
1: <html>
2: <head>
3: <title>index</title>
4: </head>
5: <body>
6: <esi:include src="/welcome.aspx" />
7: <esi:include src="hotnews.aspx" />
8: <div>
9: <h3>通知</3>
10: <ul>
11: <li>機房維護通知</li>
12: </ul>
13: </div>
14: </body>
15: <html>
注意的是welcome.aspx和hotnews.aspx如今輸出的是兩個片斷,不是完整的頁面。
這些都準備好後,就是啓用Varnish對ESI的處理了。
仍是編輯default.vcl文件。Varnish的配置能力很是強大,這個vcl是Varnish Configuration Language。剛纔咱們僅僅是配置一個後端服務器,如今讓咱們打開default.vcl仔細欣賞一下:
sub vcl_recv {
}
sub vcl_pipe {
}
sub vcl_pass {
}
sub vcl_hash {
}
sub vcl_hit {
}
sub vcl_miss {
}
sub vcl_fetch {
}
sub vcl_deliver {
}
sub vcl_error {
}
你會看到有vcl_recv,vcl_pipe,vcl_pass,vcl_hash,vcl_hit等函數。這些函數就表明一個請求進入Varnish所經過的階段(參見這裏)。就像一個管道同樣,你能夠在這些管道上作些自定義的處理。因此配置性很是強大。如今咱們只對vcl_fetch函數作一下簡單修改:
sub vcl_fetch {
if(req.url == "/welcome.aspx"){
return (pass);
}
if (req.url == "/index.aspx") {
esi;
}
}
若是請求的url是/welcome.aspx就直接pass,也就是不作任何處理,請求直接遞交給後端應用服務器(IIS)。若是請求是/index.aspx,也就是咱們上面列出的那個包含esi標籤的頁面,就對其進行ESI處理,這樣Varnish就會解析這個頁面,看看緩存中有沒有,若是有的話則從緩存中取出頁面,並將其與從後端服務器獲取的welcome.aspx片斷合併,而後直接發送回請求。
用Varnish處理ESI就這麼簡單,不過使用Varnish以前咱們還得對其某些參數進行配置,好比緩存多長時間啊等等。默認狀況下Varnish會緩存120秒,你能夠經過管理功能對其進行配置,還能夠經過在vcl裏對某些模塊進行精細的控制。
還記得咱們是怎樣啓動Varnish的麼,若是在啓動參數里加上-T 127.0.0.1:5000,那麼咱們就可使用telnet對Varnish進行管理了。咱們只須要telnet上這個端口,而後可使用不少豐富的命令了,更多細節留給你嘗試吧。
前一篇文章介紹的使用Velocity自定義標籤來實現片斷緩存和這一篇介紹的使用ESI都有本身的優缺點。
使用Velocity自定義標籤的方案工做在應用程序這一層,這樣開發人員有最大的控制權力,並且實現起來也比較簡單,所使用的也都是你們都熟悉的技術,但問題是它仍是由應用程序服務器來處理得,能夠說它減輕了一部分應用程序服務器和數據庫服務器的壓力,但還有一部分壓力仍是須要它來承擔,並且在應用程序中解決所使用的緩存一定是和應用程序所採用的緩存機制同樣(固然你也能夠爲此獨立使用一個緩存),對緩存服務器也有部分壓力。
而使用ESI的方案,它須要運維團隊的配置,甚至須要修改服務器配置的架構(添加了前端服務器),若是在多部門協調比較困難的項目中,這種方案還會遇到一些阻力。
可是它帶來的好處確實顯而易見的。首先ESI是一個W3C標準,我更傾向於採用標準的作法。並且Varnish這樣的方向代理,它原本就擅長這個,它能夠徹底把這部分壓力從應用程序服務器和緩存服務器上接管過來,並且會處理的更出色。
因而可知什麼方案都是須要權衡各方利弊,獲得一個平衡的效果啊。