转自:
http://blog.zhisou.com/space/?uid-101-action-viewspace-itemid-805
学习OSCache, 总结如下:
1。为什么需要OSCache这类的工具?
引用:
http://www.jdon.com/artichect/dbover.htm
如何尽量减少数据库访问是J2EE应用系统首要解决的问题,使用存储过程并没有解决这个问题,存储过程的执行还是属于后端,并没有缩短客户端请求所要经历的坎坷路途。解决性能问题的根本解决之道是使用对象缓存,现在, 64位CPU提供的巨大内存空间为单台缓存计算提供了硬件基础,更重要的是,这种缓存计算是可伸缩的,通过集群的缓存机制(如JBossCache),通过增加应用服务器的数量,可以提高整个业务逻辑层的缓存计算能力,抛弃过去那种为内存斤斤计较的老思维吧。
2。利用OSCache主要可以做的事情
1)POJO 对象的缓存
这是oscache的核心,事实上,jsp页面缓存功能就是基于这个来进行扩展的。
2)jsp页面的缓存
oscache提供非常好用的jsp tag library来提供jsp页面的缓存。
3。源码分析
oscache的代码量很少。分析源码的时候,主要分析com.opensymphony.oscache.base.Cache类就可以,这个又是整个 oscache的核核心类,除此之外,都是辅助类。oscache用很少的代码量来实现这么强大的功能,应该说代码还是很值得阅读的。
com.opensymphony.oscache.base.Cache的api中主要的方法如下:
public void putInCache(String key,
Object content, String[] groups,
EntryRefreshPolicy policy, String origin);
public void getFromCache(String, int, String);
public void cancelUpdate(String key);
如何使用,引用官方的docs中的一段例子如下:
String myKey = "myKey";
String myValue;
int myRefreshPeriod = 1000;
try {
// Get from the cache
myValue = (String) admin.getFromCache(myKey, myRefreshPeriod);
} catch (NeedsRefreshException nre) {
try {
// Get the value (probably from the database)
myValue = "This is the content retrieved.";
// Store in the cache
admin.putInCache(myKey, myValue);
} catch (Exception ex) {
// We have the current content if we want fail-over.
myValue = (String) nre.getCacheContent();
// It is essential that cancelUpdate is called if the
// cached content is not rebuilt
admin.cancelUpdate(myKey);
}
}
这段代码是非常使用oscache的经典代码。细说如下myValue = (String) admin.getFromCache(myKey, myRefreshPeriod);从对象缓存map中取出myKey对应的对象,两种情况可能发生: 一:如果myKey对应的对象存在(先前putInCache)并且没有过期(isStale()方法)那么getFromCache方法会正常返回。二:如果对应的对象不存在或者过期,又分为两种情况: 1)请求的线程第一个探测到对象过期,那么这个时候oscache会抛给client一个NeedRefreshException, 提示client,需要对数据进行一下刷新,怎么刷新,putInCache即可。 2)如果请求的线程并非第一个探测到对象过期,两种情况:I如果oscache.properties中对blocking设置为true,那么该线程会在此阻塞,直到putInCache在另一个线程中被调用或者是cancelUpdate被调用。II否则情况跟1)类型,也会出现 NeedRefreshException.
上面的那个例子之所以要在catch(NeedRefreshException)中进行 putInCache,又之所以要在putInCache的catch(Exception)中做cancelUpdate道理就在此,我们不希望看到一个线程在 getFromCache的位置一直阻塞下去。
补充:oscache对一个cacheEntry是否是Stale(或者说expire)的判断原则:
1。Cache.flushEntry()
2。Cache.flushAll()
3。CacheEntry.setGroups(groups); Cache.flushGroup(group)
4。createTime + refreshPeriod< now
5。cronExpiry< now
6。CacheEntry自带的EntryRefreshPolish的needRefresh方法返回true
上面的6条中的任何一条如果为true, 那么CacheEntry就是stale的,need refresh!!