Squid對(duì)動(dòng)態(tài)頁(yè)面Cache的相關(guān)須知
使用Squid做代理服務(wù)器,靜態(tài)頁(yè)面還比較簡(jiǎn)單,但動(dòng)態(tài)頁(yè)面則并沒(méi)有那么簡(jiǎn)單了。尤其現(xiàn)在大部分網(wǎng)頁(yè)都是動(dòng)態(tài)頁(yè)面,運(yùn)維人員在架設(shè)Squid的時(shí)候需要對(duì)這方面的配置留心。下面概述一下Squid對(duì)動(dòng)態(tài)頁(yè)面進(jìn)行cache的時(shí)候需要考慮的方面。
1 被cache的頁(yè)面必須對(duì)所有用戶(hù)顯示的內(nèi)容都是一致的。
如果同一個(gè)URL(包括參數(shù))對(duì)不同用戶(hù)如果顯示不同的內(nèi)容,那么cache它會(huì)使一些用戶(hù)看到其它用戶(hù)才能看到的內(nèi)容。
(我***步緩存的是訪(fǎng)問(wèn)量***的閱讀帖子的頁(yè)面,但是頁(yè)面上原來(lái)有非常復(fù)雜的權(quán)限判斷,針對(duì)這種情況,考慮到大部分信息在短期內(nèi)基本是變化不大的,只好將用戶(hù)基本信息寫(xiě)入cookie,使用前端的js來(lái)控制。雖然這樣會(huì)導(dǎo)致限制不嚴(yán)格現(xiàn)象,但是因?yàn)楫吘共皇巧虡I(yè)應(yīng)用,這些損失和性能相比還是可以接受的)
2 被cache的動(dòng)態(tài)頁(yè)面不能啟動(dòng)一個(gè)session。
因?yàn)橥ǔession都是用cookie實(shí)現(xiàn),啟動(dòng)一個(gè)session意味著服務(wù)器會(huì)發(fā)送一個(gè)Set-Cookie的HTTP頭,squid把這樣的頁(yè)面cache之后,會(huì)造成所有后續(xù)的訪(fǎng)問(wèn)用戶(hù)都在自己的瀏覽器里設(shè)置相同的cookie,這會(huì)造成嚴(yán)重的后果。所有設(shè)置cookie操作的頁(yè)面都有此類(lèi)問(wèn)題,即使不是啟用一個(gè)session。所以,這類(lèi)頁(yè)面是絕對(duì)不能cache的。但是對(duì)包含在一個(gè)已啟動(dòng)的session里的頁(yè)面進(jìn)行cache則不會(huì)有這個(gè)問(wèn)題。
(我基本上沒(méi)有用到session,set-cookie(服務(wù)器端的)在需要緩存的這個(gè)頁(yè)面也沒(méi)有,只有一個(gè)為了配合廣告活動(dòng)增加的用js來(lái)set- cookie,所以也沒(méi)有問(wèn)題)
3 用戶(hù)的訪(fǎng)問(wèn)頻度必須遠(yuǎn)遠(yuǎn)超過(guò)頁(yè)面內(nèi)容的更新頻度,否則cache的意義不大。
(這個(gè)頁(yè)面每天的pv超過(guò)100萬(wàn),所以還是想當(dāng)有必要的 )
另外,cache動(dòng)態(tài)頁(yè)面以后,由于squid會(huì)攔截用戶(hù)的請(qǐng)求,應(yīng)用程序服務(wù)器收不到被攔截的請(qǐng)求,必須保證這不會(huì)影響應(yīng)用的處理邏輯。
使用squid來(lái)cache動(dòng)態(tài)頁(yè)面有兩種方式,一種是在頁(yè)面里動(dòng)態(tài)生成幾個(gè)HTTP頭:其中一個(gè)是Last-Modified,這個(gè)頭表示頁(yè)面上次修改的時(shí)間,一般訪(fǎng)問(wèn)靜態(tài)頁(yè)面時(shí),apache會(huì)根據(jù)靜態(tài)文件的一個(gè)上次修改時(shí)戳來(lái)設(shè)置這個(gè)屬性。
(我們采用了這個(gè)last-modifyed 頭來(lái)進(jìn)行,然后在文件會(huì)發(fā)生變化時(shí)通知squid這樣可以提高squid的緩存命中率)
另一個(gè)是Expires或者Cache-Control。Expires代表頁(yè)面將在該時(shí)間之后過(guò)期,squid會(huì)從后端的應(yīng)用服務(wù)器重新獲取頁(yè)面。Cache-Control則通過(guò)一個(gè)max-age屬性來(lái)告訴squid和瀏覽器這個(gè)頁(yè)面從Last-Modified開(kāi)始的生存時(shí)間。Expires和Cache-Control只設(shè)置一個(gè)就可以。
Last-Modified和Expires的時(shí)間格式是,Wed, 14 May 2003 13:06:17 GMT。注意生成這個(gè)時(shí)間時(shí)一定要轉(zhuǎn)換成GMT時(shí)間,這樣才能使互聯(lián)網(wǎng)的全球用戶(hù)都能正確識(shí)別。max-age的時(shí)間是一個(gè)整數(shù),單位是秒。詳細(xì)的文檔請(qǐng)參考RFC2616。這幾個(gè)HTTP頭必須在所有頁(yè)面內(nèi)容輸出之前進(jìn)行設(shè)置,否則應(yīng)用程序會(huì)報(bào)錯(cuò)。
php的例子如下:
# Last-Modified時(shí)間設(shè)置為當(dāng)前時(shí)間
header("Last-Modified: " . gmdate("D, d M Y H:i:s" . " GMT";
# Expires時(shí)間設(shè)置為1小時(shí)后
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT";
第二種cache方式是使squid強(qiáng)制cache某些指定的頁(yè)面,而不管頁(yè)面中是否有前面提到的那幾個(gè)HTTP頭。相應(yīng)的配置參數(shù)舉例如下:
#下面兩行表示凡是帶參數(shù)(含有?)的URL就不cache,必須注釋掉。 #acl QUERY urlpath_regex cgi-bin \? #no_cache deny QUERY #下面兩行創(chuàng)建一個(gè)acl,它匹配兩個(gè)jsp頁(yè)面 acl CACHABLE_PAGES urlpath_regex ^/topic/readSub\.jsp acl CACHABLE_PAGES urlpath_regex ^/topic/listFrame\.jsp #下面一個(gè)acl匹配所有的動(dòng)態(tài)頁(yè)面 acl NONE_CACHABLE_PAGES urlpath_regex \? \.jsp #允許cache兩個(gè)jsp頁(yè)面 no_cache allow CACHABLE_PAGES #禁止cache其它的jsp頁(yè)面 no_cache deny NONE_CACHABLE_PAGES #下面幾行設(shè)置頁(yè)面cache的時(shí)長(zhǎng),***行cache一天,第二行cache兩分鐘 refresh_pattern ^http://post.mop.com/topic/readSub\.jsp 1440 0% 1440 ignore-reload refresh_pattern ^http://post.mop.com/topic/listFrame\.jsp 2 0% 2 ignore-reload
對(duì)于顯示帖子內(nèi)容的頁(yè)面,當(dāng)用戶(hù)回復(fù)之后,帖子內(nèi)容就改變了,為了實(shí)時(shí)刷新頁(yè)面,可以在用戶(hù)改變帖子內(nèi)容之后,打開(kāi)一個(gè)tcp連接到squid,發(fā)送一個(gè)PURGE指令,就可以將指定的URL過(guò)期,squid會(huì)重新到服務(wù)器上抓***頁(yè)面。
相應(yīng)頁(yè)面中需要增加:
Date last_modified_time = s.getLastReplyTime();
String modifySince=request.getHeader("If-Modified-Since";
SimpleDateFormat tempSdf=new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z",new java.util.Locale("en");
try{
Date modifySinceDate=tempSdf.parse(modifySince);
if (!modifySinceDate.before(last_modified_time)){
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
}catch (Exception e){
out.println("";
}
long last_modified = last_modified_time.getTime();
response.setDateHeader("Last-Modified",last_modified);
—————————————————————————————-
察看cache命中率等信息,可以用如下命令:
/data/squid/bin/squidclient -p 80 cache_object://localhost/info
其中的如下信息比較重要:
Cache information for squid: Request Hit Ratios: 5min: 41.5%, 60min: 40.1% Byte Hit Ratios: 5min: 52.3%, 60min: 50.8% Request Memory Hit Ratios: 5min: 27.7%, 60min: 30.7% Request Disk Hit Ratios: 5min: 38.3%, 60min: 39.2% Storage Swap size: 1886720 KB Storage Mem size: 39452 KB Mean Object Size: 50.85 KB Requests given to unlinkd: 1685
參考:http://www.708034.cn/?p=298
【編輯推薦】