近段時間在研究如何将Servlet/JSP中的僞動态頁面緩存到Squid中來加速Web通路,在google上搜尋"JSP在squid中的緩存"的資訊,出來的資訊比較少,後來差PHP,ASP的緩存相關資料及"深入體驗JAVA Web開發内幕——核心基礎.pdf"和"Squid中文權威指南"中的相關章節,總算實作了這個目的(有需要這兩本書的兄弟可以mail我
)。基于自己的一些了解和試驗成果,記下來供以後參考。
HTML的HTTP協定頭資訊中控制着頁面在幾個地方的緩存資訊,包括浏覽器端,中間緩存伺服器端(如:squid等),Web伺服器端。本文讨論頭資訊 中帶緩存控制資訊的HTML頁面(JSP/Servlet生成好出來的也是HTML頁面)在中間緩存伺服器中的緩存情況。
HTTP協定中關于緩存的資訊頭關鍵字包括Cache-Control(HTTP1.1),Pragma(HTTP1.0),last-Modified,Expires等。
HTTP1.0中通過Pragma 控制頁面緩存,可以設定:Pragma或no-cache。網上有非常多的文章說明如何控制不讓浏覽器或中間緩存伺服器緩存頁面,通常設定的值為no- cache,不過這個值不這麼保險,通常還加上Expires置為0來達到目的。但是如我們刻意需要浏覽器或緩存伺服器緩存住我們的頁面這個值則要設定為 Pragma。
HTTP1.1中啟用Cache-Control 來控制頁面的緩存與否,這裡介紹幾個常用的參數:
- no-cache,浏覽器和緩存伺服器都不應該緩存頁面資訊;
- public,浏覽器和緩存伺服器都可以緩存頁面資訊;
- no-store,請求和響應的資訊都不應該被存儲在對方的磁盤系統中;
- must-revalidate,對于客戶機的每次請求,代理伺服器必須想伺服器驗證緩存是否過時;
- max-age=xxx,s-max-age=xxx,替代Expires,表示應該在xxx秒後認為頁面過時,後者訓示代理伺服器中緩存(通常稱為共享緩存)的頁面過期時間。(不過我試了好多次,這個選項一直沒法實作,希望有人能補充!)
通常我們不需要緩存頁面時設定該值為"no-cache,no-store,must-revalidate"(分三行代碼設定);需要緩存頁面資訊時則設定該值為"public,max-age,s-max-age"。
Last-Modified隻頁面的最後生成時間,GMT格式;
Expires過時期限值,GMT格式,指浏覽器或緩存伺服器在該時間點後必須從真正的伺服器中擷取新的頁面資訊;
上面兩個值在JSP中設定值為字元型的GMT格式,無法生效,設定long類型才生效;
最後來看一下JSP或Servlet中如何設定緩存控制資訊的代碼:
Java代碼
- //本頁面允許在浏覽器端或緩存伺服器中緩存,時限為10秒。
- java.util.Date date = new java.util.Date();
- response.setDateHeader("Last-Modified",date.getTime());
- response.setDateHeader("Expires",date.getTime()+10000);
- response.setHeader("Cache-Control", "public");
- response.setHeader("Pragma", "Pragma");
Java代碼
- //不允許浏覽器端或緩存伺服器緩存目前頁面資訊。
- response.setHeader( "Pragma", "no-cache" );
- response.setDateHeader("Expires", 0);
- response.addHeader( "Cache-Control", "no-cache" );
- response.addHeader( "Cache-Control", "no-store" );
- response.addHeader( "Cache-Control", "must-revalidate" );
如果HTML頁面資訊中包括了Expires頭資訊,則其相關的緩存機制不再處理該頁面,而是安裝頁面的緩存控制要求來處理。是以做了上述工作後,Squid無需做任何配置上的修改(指Squid的refresh_pattern指令不處理這些頁面 )。
下面說一下Squid緩存一些靜态資源的一些原理,Squid通過refresh_pattern指令來控制使用者請求是否命中。
"Squid中文權威指南"文章中描述Squid的refresh_pattern 指令一段文章讀起來非常的拗口,就是LM_factor比率的算法,這個算法的概念翻譯的比較模糊,網絡上傳來傳去的,感覺都是搞不清楚,後來參 考"OReilly - Squid The Definitive Guide.chm"英文原文,總算明白過來
。
英文原文應用代碼
- Responses that fall between the minimum and maximum are subject to Squid's
- last-modified factor (LM-factor) algorithm. For such responses, Squid calculates
- the response age and the LM-factor and compares it to the percent value. The
- response age is simply the amount of time passed since the origin server
- generated, or last validated, the response. The resource age is the difference
- between the Last-Modified and Date headers. The LM-factor is the ratio of the
- response age to the resource age.
- LM-factor的定義是(response age)/(the resource age).
- 其中response age是指HTTP頭資訊中的age資訊。
- resource age是指HTTP頭資訊中的Date值減去Last-Modified的值轉化為秒的值。
- 各位可以通過curl指令(Linux下自帶指令)來參看一個資源傳回回來的HTTP頭詳細資訊,如下面這樣:
- curl -I http://10.0.85.125:8384/mailproxy/welcome.htm
經過試驗,這個算法是正确的,同時這裡要提醒一下,特别是對一些HTML類型的資源,max值不要設定的太大,如果設定的太大的話,有可能修改的文檔資訊 需要非常長的時間才能得到更新,因為LM-factor參數值是變化的,越來越大,分母變大的結果就是比率越來越小,總是小于我們設定的比率,導緻需要 max來控制頁面重新整理。