一起谈.NET技术,页面片段缓存(二)
在上一篇文章中,我介紹了我們用土法煉鋼的方法,使用Velocity提供的自定義標(biāo)簽實(shí)現(xiàn)片段緩存。這樣的方式雖然也解決了我們的問題,但還是引出了一些bug。而且還有點(diǎn)hack的味道(雖然我喜歡hack)。實(shí)際上對(duì)于片段緩存,業(yè)界有成熟的解決方案,還有一個(gè)所謂的W3C標(biāo)準(zhǔn):ESI(Edge Side Include) 。
ESI本身沒有什么,只是一個(gè)XML的標(biāo)簽集合。ESI和SSI(Server Side Include)很相似,做過ASP開發(fā)的都熟悉這么一個(gè)標(biāo)簽:
<!--#include src="header.inc" -->IIS碰到這么一個(gè)標(biāo)簽后,會(huì)把header.inc里面的東西合并到當(dāng)前的頁面,這樣做的好處是header.inc本身可以復(fù)用了,你可以在多個(gè)頁面include它。
ESI的功能也是類似的,只不過解析和合并它的任務(wù)一般落到緩存服務(wù)器或代理上:
<esi:include src="/welcome" /><ul>
#foreach($book in $books)
<li>$book.name</li>
#end
</ul>
比如對(duì)于上面這個(gè)片段,esi:include標(biāo)簽?zāi)抢锉緛硎菓?yīng)該顯示特定于每個(gè)用戶的歡迎信息的,就因?yàn)檫@一點(diǎn)整個(gè)頁面不能緩存太可惜了。這個(gè)時(shí)候ESI粉墨登場。緩存服務(wù)器會(huì)將整個(gè)頁面cache,然后它發(fā)現(xiàn)這兒有個(gè)ESI標(biāo)簽,它會(huì)根據(jù)src指定的地址去源服務(wù)器請(qǐng)求內(nèi)容,然后將其合并到緩存的頁面中,然后將完整的內(nèi)容發(fā)送到客戶端。整個(gè)過程類似下圖所示:
這樣我們就不需要每次都去數(shù)據(jù)庫查詢那個(gè)圖書列表了,因?yàn)閳D書列表可能更新的很緩慢。這樣大大的降低了Web服務(wù)器的壓力。
既然ESI是一個(gè)規(guī)范,那么肯定有遵循這個(gè)規(guī)范的實(shí)現(xiàn)。比如大名鼎鼎的Squid就有支持ESI的模塊。不過本文要介紹的是Varnish。Varnish是一個(gè)反向代理,使用緩存對(duì)HTTP加速,可以把它放到你的Web服務(wù)器的前面,對(duì)內(nèi)容緩存,跟Squid的目的相似。不過因?yàn)镾quid想干的事兒實(shí)在是太多,它已經(jīng)不再是一個(gè)純粹的用戶緩存加速的方向代理了,所以顯得太過于臃腫,而比較起來Varnish更專注,更輕便。根據(jù)網(wǎng)站上的數(shù)據(jù)顯示,Varnish表現(xiàn)出來的性能比Squid更好,而且占用的資源更少。
下面我就簡單的描述一下如何安裝Varnish以及配置使用ESI。
安裝
我是在Mac上安裝Varnish的,從源代碼編譯過去的。基本上是一路命令下去,在configure的時(shí)候碰到缺少libpcre,用port裝上pcre就可以了:
$wget http://repo.varnish-cache.org/source/varnish-2.1.5.tar.gz$tar zxvf varnish-2.1.5.tar.gz
$cd varnish-2.1.5
$sh autogen.sh
$sh configure
$make
$make install
根據(jù)環(huán)境不同,可能缺少一些依賴,我在安裝的過程中就缺少libpcre。
Varnish默認(rèn)是安裝在/usr/local/sbin目錄下:varnishd。是daemo。
配置
根據(jù)上面那幅圖可以看出,Varnish并不自己提供服務(wù),它只是作為一個(gè)緩存服務(wù)器。那么就必須有一個(gè)后端的服務(wù)器提供應(yīng)用程序的服務(wù)。那我們就需要讓Varnish知道到哪兒去請(qǐng)求后端服務(wù)器。這個(gè)是通過配置文件設(shè)置的,Varnish的默認(rèn)配置文件在/usr/local/etc/varish/default.vcl。
打開后我們會(huì)發(fā)現(xiàn)一段被注釋的代碼,取消注釋將其指向你的后端服務(wù)器(比如IIS):
backend default {.host = "127.0.0.1";
.port = "8080";
}
配置好后,啟動(dòng)Varnish,然后去看看效果,啟動(dòng)的命令是:
sbin yuyi$sudo ./varnishd -a 0.0.0.0:80 -f /usr/local/etc/varnish/default.vcl -s malloc,500M我簡單的介紹下這幾個(gè)選項(xiàng),更詳細(xì)的可以看man。
-a指定Varnish鑒定的地址。如果你的配置是上圖所示,那么端口應(yīng)該是80。如果你沒有指定-a,那么默認(rèn)配置使用/etc/services中的配置,一般情況下就是80。而-f指定配置文件的地址,默認(rèn)情況下就是default.vcl,除非你想使用別的配置文件。
最有趣的是-s選項(xiàng),它用來指定存儲(chǔ)方式,以及緩存的大小。比如這里是malloc,那就是使用內(nèi)存作為緩存,你還可以使用file,使用磁盤作為緩存。后面是緩存大小,500兆。還可以指定K,G,T等,大小寫都可以。
運(yùn)行后我們?nèi)g覽器打開http://127.0.0.1看看。為了測試你可以在頁面輸出一個(gè)DateTime.Now,然后刷新頁面看看是不是每次都變化。
Varnish還有個(gè)不錯(cuò)的工具:varnishlog,打開后可以看到用戶訪問的一些情況。
好了,安裝和簡單配置就介紹這么多,那如何使用ESI呢?其實(shí)很簡單,分為兩個(gè)步驟,首先將你的頁面上需要施加不同緩存策略的片段切分,放到不同的連接中。
比如原來你的首頁混沌一片:有熱點(diǎn)新聞板塊、通知板塊、還有廣告以及顯示用戶登錄的板塊。而它們?cè)瓉砗芸赡芏际怯蒳ndex.aspx處理的。如果你想有針對(duì)性的對(duì)這些板塊施加緩存策略,那么就應(yīng)該將其獨(dú)立開,使用不同的連接(控制器)來處理:
<html><head>
<title>index</title>
</head>
<body>
<p>Welcome yuyijq</p>
<div>
<h3>Hot News</h3>
<ul>
<li>慶祝奧特曼45歲生日</li>
<li>拉登掛了</li>
</ul>
</div>
<div>
<h3>通知</3>
<ul>
<li>機(jī)房維護(hù)通知</li>
</ul>
</div>
</body>
<html>
現(xiàn)在我們要拆分:
hotnews->hotnews.aspx
welcome->welcome.aspx
然后使用ESI標(biāo)簽分離:
<html><head>
<title>index</title>
</head>
<body>
<esi:include src="/welcome.aspx" />
<esi:include src="hotnews.aspx" />
<div>
<h3>通知</3>
<ul>
<li>機(jī)房維護(hù)通知</li>
</ul>
</div>
</body>
<html>
注意的是welcome.aspx和hotnews.aspx現(xiàn)在輸出的是兩個(gè)片段,不是完整的頁面。
這些都準(zhǔn)備好后,就是啟用Varnish對(duì)ESI的處理了。
配置
還是編輯default.vcl文件。Varnish的配置能力非常強(qiáng)大,這個(gè)vcl是Varnish Configuration Language。剛才我們僅僅是配置一個(gè)后端服務(wù)器,現(xiàn)在讓我們打開default.vcl仔細(xì)欣賞一下:
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 {
}
你會(huì)看到有vcl_recv,vcl_pipe,vcl_pass,vcl_hash,vcl_hit等函數(shù)。這些函數(shù)就代表一個(gè)請(qǐng)求進(jìn)入Varnish所通過的階段(參見這里)。就像一個(gè)管道一樣,你可以在這些管道上做些自定義的處理。所以配置性非常強(qiáng)大。現(xiàn)在我們只對(duì)vcl_fetch函數(shù)做一下簡單修改:
sub vcl_fetch {if(req.url == "/welcome.aspx"){
return (pass);
}
if (req.url == "/index.aspx") {
esi;
}
}
如果請(qǐng)求的url是/welcome.aspx就直接pass,也就是不做任何處理,請(qǐng)求直接遞交給后端應(yīng)用服務(wù)器(IIS)。如果請(qǐng)求是/index.aspx,也就是我們上面列出的那個(gè)包含esi標(biāo)簽的頁面,就對(duì)其進(jìn)行ESI處理,這樣Varnish就會(huì)解析這個(gè)頁面,看看緩存中有沒有,如果有的話則從緩存中取出頁面,并將其與從后端服務(wù)器獲取的welcome.aspx片段合并,然后直接發(fā)送回請(qǐng)求。
用Varnish處理ESI就這么簡單,不過使用Varnish之前我們還得對(duì)其某些參數(shù)進(jìn)行配置,比如緩存多長時(shí)間啊等等。默認(rèn)情況下Varnish會(huì)緩存120秒,你可以通過管理功能對(duì)其進(jìn)行配置,還可以通過在vcl里對(duì)某些模塊進(jìn)行精細(xì)的控制。
管理
還記得我們是怎樣啟動(dòng)Varnish的么,如果在啟動(dòng)參數(shù)里加上-T 127.0.0.1:5000,那么我們就可以使用telnet對(duì)Varnish進(jìn)行管理了。我們只需要telnet上這個(gè)端口,然后可以使用很多豐富的命令了,更多細(xì)節(jié)留給你嘗試吧。
兩種方式的比較
前一篇文章介紹的使用Velocity自定義標(biāo)簽來實(shí)現(xiàn)片段緩存和這一篇介紹的使用ESI都有自己的優(yōu)缺點(diǎn)。
使用Velocity自定義標(biāo)簽的方案工作在應(yīng)用程序這一層,這樣開發(fā)人員有最大的控制權(quán)力,而且實(shí)現(xiàn)起來也比較簡單,所使用的也都是大家都熟悉的技術(shù),但問題是它還是由應(yīng)用程序服務(wù)器來處理得,可以說它減輕了一部分應(yīng)用程序服務(wù)器和數(shù)據(jù)庫服務(wù)器的壓力,但還有一部分壓力還是需要它來承擔(dān),而且在應(yīng)用程序中解決所使用的緩存必定是和應(yīng)用程序所采用的緩存機(jī)制一樣(當(dāng)然你也可以為此獨(dú)立使用一個(gè)緩存),對(duì)緩存服務(wù)器也有部分壓力。
而使用ESI的方案,它需要運(yùn)維團(tuán)隊(duì)的配置,甚至需要修改服務(wù)器配置的架構(gòu)(添加了前端服務(wù)器),如果在多部門協(xié)調(diào)比較困難的項(xiàng)目中,這種方案還會(huì)遇到一些阻力。
但是它帶來的好處確實(shí)顯而易見的。首先ESI是一個(gè)W3C標(biāo)準(zhǔn),我更傾向于采用標(biāo)準(zhǔn)的做法。而且Varnish這樣的方向代理,它本來就擅長這個(gè),它可以完全把這部分壓力從應(yīng)用程序服務(wù)器和緩存服務(wù)器上接管過來,而且會(huì)處理的更出色。
由此可見什么方案都是需要權(quán)衡各方利弊,得到一個(gè)平衡的效果啊。
總結(jié)
以上是生活随笔為你收集整理的一起谈.NET技术,页面片段缓存(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一起谈.NET技术,通过16道练习学习L
- 下一篇: 从零开始学习OpenGL ES之五 –