開始之前
關於本教程
通過本教程,您可以了解如何使用 WAS 的動態高速緩存服務緩存 Servlet 對象,JSP 頁面,WebSphere Command 對象;如何在 cachespec.xml 文件中進行配置或者編寫唯一標識的生成類實現根據業務需要緩存同一個對象的不同版本。本教程也涉及直接操作動態緩存和使用 Cache Monitor 監控和管理動態高速緩存。
目標
完成本教程後,您應該了解如何:
配置 cachespec.xml 緩存 Servlet 或 JSP 頁面
在 cachespec.xml 中配置緩存規則緩存同一個 Servlet 對象或 JSP 頁面的不同版本
編寫 WebSphere Command 對象
編寫生成緩存唯一標識的 Java Class
直接操作動態高速緩存
安裝並使用 Cache Monitor
先決條件
要成功使用本教程,您應熟悉 Java 開發的一般知識,特別是具備服務器端 Java 開發的基礎。您應了解 WAS 和 Rational® Application Developer for WebSphere® Software (下面簡稱 RAD) 的一般概念,並熟悉部署描述符和 WAR 存檔等基本的 J2EE 概念,對 WAS 的配置和管理有所了解。
系統要求
您需要下載下列必需的(免費)應用程序,才能使用本教程及其中的示例代碼:
IBM™ Rational® Application Developer for WebSphere® Software
IBM™ WebSphere® Application Server 6.1 或者以上版本
如果讀者無法獲得 RAD 和 WAS 的正式版本,可以考慮下載和使用 RAD 的試用版 和 WebSphere® Application Server for Developers。如果讀者不想下載 RAD 的試用版,作者也提供了可供直接編譯的源代碼包 DynaCacheTutorial.zip,下載並將其解壓縮到某個目錄,修改 was.properties 文件中 was.app.dir 的值為的 WAS 的目錄,然後運行“ant war”進行編譯。使用這種方法用戶可以用您所喜歡的編輯器直接修改相應的代碼並進行編譯安裝。
硬件配置應包括:支持上面列出的軟件,並且至少具有 2GB 內存(推薦為 3GB)。本教程中的說明基於 Microsoft® Windows® 操作系統,但也適用於 Linux® 和 UNIX® 操作系統。
引言
WAS 動態高速緩存概述
高速動態緩存做為 WAS 的一個擴展服務從 5.0.2 開始就被包含在從 WAS Express 開始的各個版本。該服務可以緩存 WebSphere Command 對象、Servlet 和 JavaServer Pages(JSP)的輸出,從而明顯提升應用程序性能。動態高速緩存服務位於應用程序服務器 Java 虛擬機(JVM)內部,通過攔截對可高速緩存對象的調用隱式的實現了對緩存的調用,程序員甚至意識不到它的存在。圖 1 展示了緩存命中和不命中的兩種情況下系統的流程,如果緩存命中將避免執行後面復雜的商業邏輯,業務邏輯的執行時間大大縮短了。
圖 1. 緩存命中和失敗
在 WAS 中開啟 Servlet cache
默認情況下 WAS 是開啟動態高速緩存服務的,用戶可以按照以下的步驟檢查該服務是否開啟並開啟 Servlet 緩存
登錄 WAS 的管理控制台,如 http://localhost:9060/ibm/console
輸入管理員的用戶名和密碼
單擊 Servers > WebSphere application servers > server1,在 Configuration 選項卡下面選擇 Container Services > Dynamic cache service,如 圖 2
確保在 圖 3“Enable service at server startup”被選中(在 WAS 7 則沒有這個選項,用戶是不能夠關閉動態高速緩存服務的)
圖 2. 打開動態高速緩存服務
圖 3. 確認動態高速緩存已被開啟
然後確認 Servlet 的緩存被開啟了,默認情況下 WAS 是不開啟該選項的,依照如下的步驟啟動該功能
單擊 Servers > WebSphere application servers > server1,在 Configuration 選項卡下面選擇 Web Container Settings > Web container
在 圖 4 選中“Enable Servlet caching”,然後選擇“OK”按鈕
在接下來的界面選擇“Save”連接,保存修改
圖 4. 開啟 Servlet 緩存
在本文中我們會創建一個簡單的 Web 應用,對顯示的時間進行緩存。該例子會有 Servlet,JSP,WebSphere Command 等多個版本
創建 WEB 工程
按照以下步驟創建一個 WEB 工程
啟動 Rational Application Developer for WebSphere
創建一個 Dynamic Web Project,以 DynaCacheTutorial 為工程的名字,將 Dynamic Web Module version 選擇為 2.4,這樣編譯的 WAR 就可以在 WAS 6.1 中部署了
同時創建一個名為 DynaCacheTutorialEAR 的 EAR 工程,將 EAR version 設為 1.4,同樣這樣確保可以部署到 WAS 6.1 上面
將 DynaCacheTutorial 加到 DynaCacheTutorialEAR 工程中去
將 DynaCacheTutorialEAR 部署到 WAS 上確保運行沒有錯誤
緩存 Servlet
普通的 Servlet
在本節開始以前請確保您按照 在 WAS 中開啟 Servlet cache 一節的方法啟用了 Servlet 緩存。下面從一個簡單的 Servlet 例子開始介紹如何使用動態高速緩存,依照下面的的步驟創建一個 Servlet。
選擇 File > Other > Web > servlet
在接下來的界面 Java package 填為 demo,Class name 填為 UnCachedServlet,選 Next 進入下一個界面
在接下來的界面接受缺省的設置(Name:UnCachedServlet,URL Mappings:/UnCachedServlet),選 Next 進入下一個界面
在接下來的界面中取消 doPost() 選中,選 Finish 結束設置
將 doGet() 方法替換如 清單 1 所示
清單 1. 不被緩存的 Servlet - UnCachedServlet.java
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.println(" The Current time is " + new java.util.Date() + "<br />");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
清單 1 是一個非常簡單的在頁面上顯示當前時間的 Servlet,在 WAS 部署成功以後,在浏覽器的地址欄中輸入如下的地址 http://localhost:9080/DynaCacheTutorial/UnCachedServlet,輸出可能如 圖 5(當然您得到的是當前的時間)
圖 5. 未被緩存的 Servlet 的輸出
每當您刷新這個頁面的時候,輸出的時間應該如預期的總是返回當前時間。
被緩存的 Servlet
接著創建另一個 Servlet(demo.CachedServlet,Servlet 名字為 CachedServlet,映射為 /CachedServlet),並嘗試緩存其內容,將其 doGet() 方法替換如 清單 2
清單 2. 被緩存的 Servlet - CachedServlet.java
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.println("<p>The time will not change unless time is out or cache is cleared</p>");
out.println(" The time is " + new java.util.Date() + " <br />");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
System.out.println(this.getClass().getName() + ".doGet() run!!!");
}
在 WAS 上面部署後在浏覽器的地址欄中輸入如下的地址 http://localhost:9080/DynaCacheTutorial/CachedServlet,輸出可能如 圖 6
圖 6. 被緩存的 Servlet 的輸出
但是當再次刷新的時候,時間仍然是馬上發生變化的,緩存顯然並沒有起作用。緩存不是無緣無故的就發生了的,是需要進行配置。下面做最重要的步驟,在 WebContent/WEB-INF 下創建一個名為 cachespec.xml 的文件,其內容如 清單 3
清單 3. 在 cachespec.xml 指定 Servlet 的緩存策略
<?xml version="1.0"?>
<!DOCTYPE cache SYSTEM "cachespec.dtd">
<cache>
<cache-entry>
<class>servlet</class>
<name>/CachedServlet</name>
<property name="store-cookies">false</property>
<property name="save-attributes">false</property>
<cache-id>
<priority>0</priority>
<timeout>300</timeout>
</cache-id>
</cache-entry>
</cache>
手工重新部署或者等待 RAD 自動重新部署以後再次刷新 http://localhost:9080/DynaCacheTutorial/CachedServlet,打印出來的時間竟然神奇般的凝固不變了。但超過五分鐘以後刷新時間就會發生變化。就這樣通過創建了一個 XML 文件並在其中指定需要緩存的 Servlet 的名字和時間就完成了 Servlet 的緩存了,而代碼本身沒有任何的改變。這就是動態高速緩存強大的地方,它盡可能的采取了非侵入的方法不會污染已有的代碼了。
緩存 JSP
Servlet 現在已經很少被用來產生頁面,下面介紹如何在動態高速緩存中緩存 JSP 頁面。依下面的步驟創建一個 JSP 頁面
選擇 File > Others
在文件類型中選擇 Web Page,選擇 Next 進入下一個界面
選擇 JSP,文件名為 cached.jsp,選擇 Finish 完成設置
將 JSP 頁面的主體部分的替換如 清單 4 所示
然後在 cachespec.xml 中添加如 清單 5 所示的內容
清單 4. 被緩存的 JSP
<body>
<p>The time will not change unless time is out or it's cleared</p>
The time is: <%= new java.util.Date() %>
<% System.out.println(this.getClass().getName() + " Run Business Logic"); %>
</body>
清單 5. 在 cachespec.xml 緩存 JSP
<cache-entry>
<class>servlet</class>
<name>cached.jsp</name>
<property name="store-cookies">false</property>
<property name="save-attributes">false</property>
<cache-id>
<priority>0</priority>
<timeout>300</timeout>
</cache-id>
</cache-entry>
通過浏覽器訪問 http://localhost:9080/DynaCacheTutorial/cached.jsp,得到的結果和上一章 Servlet 一樣的緩存效果效果。在 WAS 中緩存 JSP 就是如此的簡單。
緩存不同的內容
前面無論是 Servlet 還是 JSP 總是輸出同樣的結果,實際應用中這種情況很少出現;往往是根據不同的輸入參數,輸出不同的結果。下面就模擬這樣場景,根據不同的用戶緩存不同的時間。首先在 WebContent 目錄下創建兩個 parameter.jsp 和 embed.jsp 兩個 JSP 文件,內容分別如 清單 6 和 清單 7,然後在 cachespec.xml 中添加如 清單 8 的內容。請注意緩存的是 embed.jsp 而不是 parameter.jsp。
清單 6. parameter.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>parameter.jsp</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>
<body>
<%
if (request.getParameter("submit") != null) {
request.setAttribute("name", request.getParameter("name"));
} else {
request.setAttribute("name", "WAS");
}
%>
<p>Input Your Name:</p>
<form action="parameter.jsp">
<input type="text" name="name" value="<c:out value='${name}'/>"/>
<input type="submit" name="submit" value="Submit"/>
</form>
<% if (request.getParameter("submit") != null) { %>
The current time is: <%=new java.util.Date() %> <br />
<jsp:include page="embed.jsp"></jsp:include>
<% } %>
</body>
</html>
清單 7. embed.jsp
<%=request.getParameter("name") + "'s cached time is: "%><%= new java.util.Date() %>
<% System.out.println("In " + request.getParameter("name") + " embed.jsp");%>
清單 8. embed.jsp 的 JSP 的緩存策略
<cache-entry>
<class>servlet</class>
<name>embed.jsp</name>
<property name="store-cookies">false</property>
<property name="save-attributes">false</property>
<cache-id>
<component type="parameter" id="name">
<required>false</required>
</component>
<priority>0</priority>
<timeout>300</timeout>
</cache-id>
</cache-entry>
在浏覽器中輸入 http://localhost:9080/DynaCacheTutorial/parameter.jsp,分別輸入 WAS 和 Rational,點擊“Submit”按鈕,您會發現 WAS 和 Rational 緩存的時間各不相同,且相互不影響。先觀察一下 Cache Monitor 的輸出(Cache Monitor 的安裝和使用可以參見 Cache Monitor 一章),該輸出類似於 圖 7,明顯 embed.jsp 有兩個不同的頁面緩存。觀察其唯一標識(Cache ID)的差別就是 name=?。動態高速緩存是如何做到這個的?關鍵在於 cachespec.xml 中緩存策略使用了 request 中的名為 name 的參數做為緩存唯一標識。從這個例子很容易將其擴展到如下兩種應用環境:
實現一個頁面根據不同的輸入參數緩存不同的結果
只緩存頁面的一個部分,對於 Master-Detail 頁面結構的設計非常有用
圖 7. 同一個頁面的多個緩存版本
讀者可以把動態高速緩存看成一個復雜的 hashtable,可以通過唯一標識定位到緩存的一個對象。
Java Command 對象
有時候要緩存不僅僅是 Servlet 和 JSP 頁面,用戶還想緩存一個 Java 類的調用結果。WAS 提供了一種 command 的模式幫助用戶緩存 Java 對象。使用該模式前用戶必須提供所有的前置條件,然後運行 execute() 方法,該方法會處理緩存的命中,最後獲取所需的數據。如 圖 8 所示,要取得股票的價格,用戶必須先調用 setSymbol() 提供股票代碼,然後運行取價格的邏輯 execute(),最後調用 getPrice() 獲得價格。下面是編寫 command 對象的一般步驟
定義一個 Java 類擴展 com.ibm.websphere.command.CacheableCommandImpl 類並實現相應的接口
編寫 setXXX() 方法用於設置前置條件
重載 isReadyToCallExecute() 方法檢查前置條件是否完備
重載 performExecute() 方法執行真正的邏輯
選擇是否重載 setOutputProperties() 方法只從動態高速緩存中取回部分屬性
編寫 getXXX() 方法返回所需要的結果
圖 8. command 模式
下面用 command 模式實現前面 parameter.jsp 的功能。首先定義如 清單 9 的接口,實現類類似於 清單 9
清單 9. command 的接口
package demo;
import java.util.Date;
public interface DateService {
String getUser();
Date getCached();
Date getUnCached();
}
清單 10. DateService 的實現
package demo;
import java.util.Date;
import com.ibm.websphere.command.CacheableCommandImpl;
import com.ibm.websphere.command.TargetableCommand;
public class DateServiceCommand2 extends CacheableCommandImpl implements DateService{
private static final long serialVersionUID = 1L;
@Override
public boolean isReadyToCallExecute() {
return user != null;
}
@Override
public void performExecute() throws Exception {
// Do nothing here
}
// Try to comment this function to see the result
@Override
public void setOutputProperties(TargetableCommand paramTargetableCommand) {
DateServiceCommand2 command = (DateServiceCommand2) paramTargetableCommand;
cached = command.cached;
}
@Override
public String toString() {
return String.format("<user:%s, cached:%s, uncached:%s>", user, cached, unCached);
}
public Date getCached() {
return cached;
}
public Date getUnCached() {
return unCached;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
private String user = null;
private Date cached = new Date();
private Date unCached = new Date();
}
在 cachespec.xml 中添加如 清單 11 的策略用於緩存前面編寫的 command 對象。
清單 11. 緩存 command 的策略
<cache-entry>
<class>command</class>
<name>demo.DateServiceCommand2</name>
<cache-id>
<component type="method" id="getUser">
</component>
<priority>0</priority>
<timeout>300</timeout>
</cache-id>
<invalidation>
</invalidation>
</cache-entry>
編寫如 清單 12 的 JSP 文件,調用該 command 對象
清單 12. 使用 command 的 JSP 頁面
<body>
<% if (request.getParameter("submit") != null) {
request.setAttribute("name", request.getParameter("name"));
} else {
request.setAttribute("name", "WAS");
}%>
<p>Input Your Name</p>
<form action="command2.jsp">
<input type="text" name="name" value="<c:out value='${name}'/>"/>
<input type="submit" name="submit" value="Submit"/>
</form>
<%
if (request.getParameter("submit") != null) {
String user = request.getParameter("name");
demo.DateService service = new demo.DateServiceCommand2();
((demo.DateServiceCommand2) service).setUser(user);
try {
((demo.DateServiceCommand2) service).execute();
%>
Current time is: <%=service.getUnCached() %> <br />
<%=service.getUser()+"'s cached time is:" %> <%=service.getCached() %>
<%
}
catch (Exception ex) {
ex.printStackTrace();
}
}
%>
</body>
使用 Java 代碼產生唯一標識
有時候唯一標識是無法通過簡單的配置產生,比如需要根據登錄的用戶所在的地區進行緩存。對於這種情況動態高速緩存提供了使用 Java 代碼生成唯一標識的方法。用戶需要一個 Java 類來實現 Servlet 的 com.ibm.websphere.servlet.cache.IdGenerator 接口,如果是 Web Service 則實現 com.ibm.websphere.webservices.IdGenerator 接口,command 類則是 com.ibm.websphere.command.CommandIdGenerator 接口。無論是那種方法用戶都需要實現 getId() 這個方法,返回一個 String 值表示合法的標識,如果不希望被緩存則返回 null。清單 13 是 command3 類的標識生成類,清單 13 則是在 cachespec.xml 中使用該唯一標識生成類。
清單 13. command3 的 idgenerator 類
package demo;
import java.util.ArrayList;
import com.ibm.websphere.command.CacheableCommand;
import com.ibm.websphere.command.CommandIdGenerator;
public class DateServiceIdgenerator implements CommandIdGenerator {
@SuppressWarnings("unchecked")
public String getId(CacheableCommand arg0, ArrayList arg1) {
DateService command = (DateService) arg0;
if (command != null)
return command.getUser();
else
return null;
}
}
清單 14 是 command3 緩存策略
清單 14. 用 idgenerator 緩存 command
<cache-entry>
<class>command</class>
<name>demo.DateServiceCommand3</name>
<cache-id>
<idgenerator>demo.DateServiceIdgenerator</idgenerator>
<priority>0</priority>
<timeout>300</timeout>
</cache-id>
<invalidation>
</invalidation>
</cache-entry>
更詳細的內容可以參考附件中的 command3.jsp 。標識生成類同樣也適用於 Servlet、JSP 等的緩存。
直接對動態緩存編程
有時候用戶不希望使用這麼復雜的編程模型,而是希望直接將數據存入動態高速緩存。這時可以使用 com.ibm.websphere.cache.DistributedMap 接口來操作動態高速緩存中的一個實例,用 get() 方法獲得緩存對象,用 put() 方法將對象放入緩存,用 invalidate() 方法清除緩存。
獲得緩存示例
有兩種方法獲得 DistributedMap 的一個實例。
調用 com.ibm.websphere.cache.DynamicCacheAccessor 類的靜態方法 getDistributedMap() 獲得 Servlet 緩存實例,清單 15 演示了這種用法,但是該方法已經被聲明為 Deprecated,不建議使用
如 清單 15 通過 JNDI 查詢獲得緩存實例
清單 15 和 清單 16 同時也演示了 DistributedMap 的一些常用方法。
清單 15. directuse1.jsp 用靜態方法獲得緩存實例
<body>
<% com.ibm.websphere.cache.DistributedMap cache
= com.ibm.websphere.cache.DynamicCacheAccessor.getDistributedMap();
java.util.Date time = null;
String key = "Cached Time in baseCache";
if (!cache.containsKey(key)) {
time = new java.util.Date();
cache.put(key, time, 0, 60, 0, com.ibm.websphere.cache.EntryInfo.NOT_SHARED, null);
}
request.setAttribute("cached", cache.get(key));
request.setAttribute("uncached", new java.util.Date());
%>
<c:out value="Cached time is:${cached}" /><br/>
<c:out value="UnCached time is:${uncached}" /><br/>
</body>
清單 16. directuse2.jsp 通過 JNDI 查詢獲得緩存實例
<body>
<% com.ibm.websphere.cache.DistributedMap cache = null;
javax.naming.InitialContext ic = new javax.naming.InitialContext();
cache = (com.ibm.websphere.cache.DistributedMap)
ic.lookup("services/cache/distributedmap");
java.util.Date time = null;
String key = "Cache From JNDI";
if (!cache.containsKey(key)) {
time = new java.util.Date();
cache.put(key, time, 0, 60, 0, com.ibm.websphere.cache.EntryInfo.NOT_SHARED, null);
}
request.setAttribute("cached", cache.get(key));
request.setAttribute("uncached", new java.util.Date());
%>
<c:out value="Cached time is: ${cached}" /><br/>
<c:out value="UnCached time is: ${uncached}" />
</body>
直接操作動態高速緩存對象則不需要在 cachespec.xml 做任何配置。WAS 會重新載入 cachespec.xml,然後刷新相應的緩存策略,這樣用戶可以在系統運行的時候動態調整緩存策略。直接操作緩存不會利用該特性了,相對不是那麼方便,建議盡可能不要直接操作動態高速緩存。
清除緩存
動態高速緩存只有一種失效模式:定時失效。這樣就帶來了一個問題,如果被緩存的數據時效要求很高,如股票的價格,那麼如果緩存的價格和當前價格不一致就會造成巨大的損失,要是可以及時清除緩存就可以避免這類問題。清單 17 展示了如何清除一條緩存。清除緩存是比較容易的,關鍵是找到合適的清除緩存的時機,在緩存命中率和數據的時效性中得到一個最佳平衡。
清單 17. invalidate.jsp 演示如何清楚緩存
<body>
<% com.ibm.websphere.cache.DistributedMap cache =
com.ibm.websphere.cache.DynamicCacheAccessor.getDistributedMap();
java.util.Date time = null;
String key = "Cached Time in invalidate.jsp";
if (request.getParameter("invalidate") != null) {
cache.invalidate(key);
}
if (!cache.containsKey(key)) {
time = new java.util.Date();
cache.put(key, time, 0, 300, 0, com.ibm.websphere.cache.EntryInfo.NOT_SHARED, null);
}
request.setAttribute("cached", cache.get(key));
request.setAttribute("uncached", new java.util.Date());
%>
<p>This page demo how to invlidate a cache item</p>
<c:out value="Cached time is:${cached}" /><br/>
<c:out value="UnCached time is:${uncached}" />
<br />
<form action="invalidate.jsp" method="post">
<input type="submit" name="invalidate" value="Invalidate">
</form>
</body>
Cache Monitor
安裝 Cache Monitor
WAS 提供了一個非常強大工具 Cache Monitor 幫助診斷和分析動態高速緩存的使用。該工具安裝包位於 AppServer 的 installableApps 目錄下,文件名為 CacheMonitor.ear。依照下面的步驟進行安裝
登錄 WAS 的管理控制台,如 http://localhost:9060/ibm/console
輸入 WAS 管理員的用戶名和密碼
選擇 Applications > New Application > New Enterprise Application
在 Path to the new application 選擇 Local file system,通過“Browse...”按鈕定位到 CacheMonitor.ear 的路徑
在下一個界面選擇“Fast Path - Prompt only when additional information is required.”
在“Step 1: Select installation options”接受默認值,選擇 Next 按鈕進入下一步
在“Step 2: Map modules to servers”選擇 server1,選擇 Next 按鈕進入下一步
在“Step 3: Summary”選擇 Finish 按鈕結束安裝
在接下來的界面選擇 Save 連接保存設置
安裝 Extend Cache Monitor
默認安裝的 Cache Monitor 提供的功能比較有限,讀者通過下載 Extend Cache Monitor 擴展其功能,具體步驟如下
下載 Extend Cache Monitor,WAS 7.0、6.1、6.0 對應的版本各不相同,請根據您的 WAS 的版本選擇
登錄 WAS 的管理控制台,如 http://localhost:9060/ibm/console
輸入 WAS 管理員的用戶名和密碼
選擇 Applications > Application Types > WebSphere enterprise applications
在如 圖 9 所示的界面,選擇 Dynamic Cache Monitor,點擊 Update 按鈕
根據下載站點上的提示進行安裝
圖 9. 安裝 Extend Cache Monitor
設置 Cache Monitor 的訪問控制
現在還無法使用 Cache Monitor,還需要按照下面的步驟設置訪問控制
在 圖 9 中選擇 Dynamic Cache Monitor,對其進行訪問控制設置
在接下來的界面中選擇 Detail Properties > Security role to user/group mapping,點擊進入配置界面
選中 administrator,再選擇“Map Special Subjects”
可以參考 圖 10 選擇 Everyone 有管理員權限,這樣匿名用戶也可以使用 Cache Monitor 了(在生產環境中不建議如此設置)
選擇 OK 按鈕推出,在接下來的界面選擇 Save 保存設置
圖 10. 設置訪問控制
使用 Cache Monitor
在使用 Cache Monitor 以前請確保該應用已經啟動。在浏覽器地址欄中輸入 http://localhost:9080/cachemonitor,會出現如下 圖 11 的界面
圖 11. Cache Monitor
然後訪問 http://localhost:9080/DynaCacheTutorial/CachedServlet 和 http://localhost:9080/DynaCacheTutorial/cached.jsp 兩個連接。接著切換到 Cache Monitor 界面,看到和 圖 12 類似的結果。點擊“/DynaCacheTutorial/cached.jsp:requestType=GET”連接進入如 圖 13 所示的界面,在這裡我們看到了內容和 http://localhost:9080/DynaCacheTutorial/cached.jsp 是一致的,這個功能很有利於調試。另一個有用的調試功能是點擊每一條被緩存內容前面的 Invalidate 按鈕清除這條內容。
圖 12. Cache Monitor 顯示 Servlet 和 JSP 被緩存了
圖 13. 被緩存的 JSP 的內容
Cache Monitor 還有一個重要的作用就是分析緩存的效率,和所有的緩存的一樣我們期望緩存的命中率越接近 100% 越好,計算方法是用 圖 12 中的“Cache Hits”減掉“Cache Misses”以後的值除以“Cache Hits”,如 圖 14 中緩存命中率為 99%,一個非常理想的值。“Used Entries”表示當前緩存被使用的情況,當緩存被填滿的時候,如果沒有設置“Disk Offload”,那麼低優先級級的緩存項就會被從動態高速緩存中剔除出去。
圖 14. 緩存命中率的統計
cachespec.xml 的結構
在前面的例子中無論是 Servlet 還是 JSP 頁面本身沒有什麼特殊的地方,關鍵在於 cachespec.xml 文件,它神奇的指定了緩存的策略。本章將重點講解一下該文件核心部分的結構,該文件中每一條 cache-entry 均對應這一個 Servlet、JSP 或者 WebSphere command。下面介紹一下幾個關鍵的域
class 指定需要緩存的對象,合法的取值可以是 command,Servlet,webservice,JAXRPCClient,static,portlet
name 指定被緩存的對象的名字,不同的對象取值類型是不同的,Servlet 和 JSP 取 URI,command 對象取類的全名,portlet 取 portlet 名字
property,建議 store-cookies 和 save-attributes 為 false,這樣可以減少由於序列化失敗導致在集群中緩存復制失敗的可能性
cache-id 指定對象的不同調用生成唯一標識。這些標識是由用戶編寫的定制 Java 代碼或每個高速緩存條目的高速緩存策略中定義的規則構建產生,用戶可以為一個對象指定多個標識生成規則。如果高速緩存標識生成規則產生不了有效的標識,對象就不被緩存。每個 cache-id 元素都定義高速緩存對象的規則,並且它是由子元素組件(timeout、inactivity、priority、property、 idgenerator 和 metadatagenerator)組成的。更多的細節參考信息中心。後面會重點介紹 idgenerator。
結束語
您可以選擇直接部署編譯好的 war 包,並在浏覽器中輸入 http://localhost:9080/DynaCacheTutorial,裡面有到各個頁面的快速連接,這樣您就可以很容易體會一下動態高速緩存的強大。
通過本教程您學習了如何使用 WAS 的動態高速緩存,感受了其強大的功能和使用的便利。如果使用得當可以讓應用系統的性能提升事半功倍。但是讀者如需要知道更多的關於動態高速緩存的內容請參考後面提及的參考資料。
下載:
http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1008_shenhf_wascache/1008_shenhf_wascache.html?ca=drs-