Fork me on GitHub

OSCache简述

官网: http://www.opensymphony.com/oscache [缓存产品有:EHCahce、OSCache、JbossCache(分布式缓存)]
例子:
http://www.java.net/downloads/oscache/OSCache/2.4.1/oscache-example.war

OSCache是什么

OSCache是OpenSymphony这个开源项目众多Projects中的一个。他是一个高效的J2EE缓存框架,能够很好的解决动态网站速度的问题。下面来看下OSCache解决了动态网站的哪些令人郁闷的问题。
   1.缓存动态内容:其实我们的动态网页上一般只有一部分是动态的(表头,表尾一般是不变的),如果我们缓存整个网页显然不成,因为有部分是随着请求有可能变的。OSCache提供的方式是允许我们只缓存一部分网页。
   2.缓存2进制内容:产生的图片和PDF文件在服务器加载的时候非常的耗时。OSCache解决这个问题是通过一个Servlet2.3的缓存过滤功能,然后能够缓存任意的URI(比如一个完整的页面或者是一个产生的图片/PDF文件)
   3.容错:有这种情况或许我们会遇到,就是当一个动态的网页出现错误。即便我们的页面有95%都加载完毕,但就是由于这个错误,整个页面就会返回错误的提示或页面。OSCache允许我们提供出现错误时的缓存内容,如果出现就适时的提示出来了。
   除了上面的这些Servlet的特征外,OSCache完全可以充当任何一个java程序的缓存方案。OSCache 的一般特征如下:
   1.缓存任意对象:可以不受限制的缓存JSP的一部分或是Http请求,任何的Java对象都可以被缓存。
   2.全面的API:通过API可以完完全全的控制OSCache的任何特性。
   3.持久缓存:我们可以把认为重要的数据缓存到硬盘上。
   4.支持集群:集群缓存数据能被单个的进行参数配置,不需要修改代码(如果需要集群缓存,把jgroups.jar放入classpath)
   5.缓存记录的过期:你可以有最大限度的控制缓存对象的过期,包括可插入式的刷新策略(如果默认性能不需要时)。

OSCache运行环境

如果用到OSCache Tag Library的话,需要Servlet2.3和JSP1.2的支持。如果是直接用OSCache API的话那么就不需要Servlet容器的支持。
目前可以正常运行的Web容器:
1.OrionServer(版本1.4.0和更高)
2.JRun(3.0或更好)
3.WebLogic(8.1或以上)
4.Websphere(5.0或以上)
5.Resin(1.2.3或以上)
6.TomCat(4.0或以上)
7.iPlanet(6.0或以上)
用到缓存过滤需要Servlet2.3支持.目前知道的可以个工作在OrionServer,WebLogic,Tomcat上.OSCache需要Java的版本至少是java 1.4

OSCache缓存配置

从src\webapp\WEB-INF\classes或etc目录取得oscache.properties文件,放在CLASSPATH下src根目录,oscache.properties包含了对OSCache运行特征值的设置信息

配置项

含义

可选值

缺省值

cache.memory

是否进行内存缓存

true、false

true

cache.capacity

内存缓存容纳的最大对象数

整数

不限制(指定负数也相当于不限制),也就是缓存的对象从不被清除

cache.algorithm

缺省的运算规则。要指定运算规则,就必须指定有效的cache.capacity值(正整数)。规则是一些类,在包com.opensymphony.oscache.base.algorithm下

LRUCache(最近使用)、FIFOCache(先进先出)、UnlimitedCache(不限制)

不限制cache.capacity时为UnlimitedCache,If you specify a size but not an algorithm, the cache algorithm used will be LRUCache

cache.blocking

当缓存中的某条数据更新时(比如与数据库不同步,存在不新鲜的数据),对客户请求返回更新前的数据。这样就提供了更好的性能。

true、false

false

cache.unlimited.disk

硬盘缓存是否有限制。缺省为cache.capacity指定的值

true、false

false

cache.persistence.class

做持久化操作的类名。这个类必须实现PersistenceListener接口,从而将缓存数据持久化到文件、数据库、LDAP。OSCache给出一个基于文件系统的实现,并且使用对象的toString()方法生成要持久化数据的文件名。HashDiskPersistenceListener和 DiskPersistenceListener要求必须同时设置cache.path属性。

com.opensymphony.oscache.plugins.

diskpersistence.DiskPersistenceListener 

 

cache.path

硬盘持久化时存放文件的目录。如果目录不存在OSCache会自动创建。

Windows系统: c:\\myapp\\cache

其它:/opt/myapp/cache

 

cache.persistence.overflow.only*

是否只有当指定的内存缓存已经满时才进行持久化。推荐使用true,flase是为向后兼容。

true
false

false

cache.event.listeners

一系列用逗号分割的类,这些类必须实现CacheEntryEventListener或(和)CacheMapAccessEventListener接口,CacheEntryEventListener监听缓存的add/update/flush/remove事件,CacheMapAccessEventListener监听缓存的access事件,从而可以跟踪并统计缓存的执行效率。JavaDoc API for further details.

 

 

cache.key

指定在application或session范围里缓存的对象的key,这个key被ServletCacheAdministrator(由此自定义的tags)使用。

 

__oscache_cache

cache.use.host.domain.in.key

If your server is configured with multiple hosts, you may wish to add host name information to automatically generated cache keys. If so, set this property to true

true
  false

false

cache.cluster.multicast.ip

见集群的相关说明

 

 

cache.cluster.properties

见集群的相关说明

 

 

缓存方式

   1.缓存对象(内存缓存,磁盘缓存)
将一个对象以key-value的形式放入缓存中,主要通过GeneralCacheAdministrator类来实现。写了个单例,其实是不必要的

public class OSCacheHelper<T> extends GeneralCacheAdministrator {
    private static final long serialVersionUID = 1L;
    private static Logger logger = Logger.getLogger(OSCacheHelper.class);
    private static Object lock = new Object();
    private static OSCacheHelper instance;
    private OSCacheHelper() {
    }
    public static OSCacheHelper getInstance() {
        if (instance == null) {
            synchronized (lock) {
                if (instance == null) {
                    instance = new OSCacheHelper();
                }
            }
        }
        return instance;
    }

    /**
     * put on Object in a cache
     */
    public void putToCache(String key, T data) {
        try {
            this.putInCache(key, data);
            logger.info(key + " put in Cache success");
        } catch (Exception e) {
            logger.info(key + " put in Cache faile"+e.getMessage());
        }
    }

    /**
     * get on Object from the Cache
     */
    public T getFromCache(String key, int time) {
        try {
            return (T) this.getFromCache(key, time);
        } catch (Exception e) {
            logger.info(key + " is not found in Cache");
        }
        return null;
    }

    /**
     * remove an Object in a cache
     */
    public void removeEntry(String key) {
        this.removeEntry(key);
    }

    /**
     * flushes a single cache entry
     */
    public void flushEntry(String key) {
        this.flushEntry(key);
    }

    /**
     * flush the entire cache immediately
     */
    public void flushAll() {
        this.flushAll();
    }

    /*
     * cancel a pending cache update
     */
    public void cancelUpdate(String key) {
        this.cancelUpdate(key);
    }

    /**
     * 删除指定日期所有被缓存的对象
     */
    public void flushAll(Date date) {
        this.flushAll(date);
    }
}

SpringMVC下测试

@Controller
public class OscaheController extends BaseCache {
    private static final long serialVersionUID = 1L;
    protected static Logger logger = Logger.getLogger(OscaheController.class);

    // 文件缓存读取
    @RequestMapping(value = "putCache.shtml")
    public String putCache() {
        Map<String, List<User>> ms_map = new HashMap<String, List<User>>();
        List<User> list = new ArrayList<User>();
        for (int j = 0; j < 100; j++) {
            for (int i = 0; i < 500; i++) {
                User user = new User();
                user.setId(i);
                user.setEmail(2538XXXXX + i + "@163.com");
                user.setNickname("Irving");
                user.setUsername("sd" + new Date().toLocaleString());
                user.setAdddate(new Date());
                list.add(user);
            }
            ms_map.put(String.valueOf(list.get(0).getId()), list);
        }
        //this.putToCache("CACHE_NEW_MS_PRICE_OBJ", ms_map);
        OSCacheHelper.getInstance().putToCache("CACHE_NEW_MS_PRICE_OBJ", ms_map);
        return "putCache";
    }

    @RequestMapping(value = "loadCache.shtml")
    public void loadCache() {
        Map<String, List<User>> ms_map = new HashMap<String, List<User>>();
        ms_map = (Map<String, List<User>>) this.getFromCache("CACHE_NEW_MS_PRICE_OBJ", 31536000);
        for (Object o : ms_map.keySet()) {
            List<User> user = ms_map.get(o);
            for (User u : user) {
                logger.info("ID:" + u.getId() + " Email:" + u.getEmail() + " UserName:" + u.getUsername());
            }
        }
    }
}

2.局部页面缓存(导入标签库)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page language="java" import="java.text.*" %>  
<%@ taglib uri="http://www.opensymphony.com/oscache" prefix="cache"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>页面局部缓存</title>
  </head>
  <body>
    <%
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    %>  
    <div>  
        <cache:cache key="cacheDate" scope="session" time="10">   
            <h2>使用缓存,在10秒内不进行更新</h2>  
            <div><%
                  String cacheTime = sf.format(new Date());
                      out.println(cacheTime);
              %>  
            </div>  
        </cache:cache>  
    </div>  
    <hr>  
    <div>  
        <h2>不使用缓存</h2>  
        <div><%
              String nowTime = sf.format(new Date());
              out.println(nowTime);
          %></div>  
    </div> 
  </body>
</html>

3.整个页面缓存

<filter>   
      <filter-name>CacheFilter</filter-name>   
        <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>    
        <init-param>    
         <param-name>time</param-name>   
         <param-value>500</param-value>   
      </init-param>    
      <init-param>     
         <param-name>scope</param-name>    
         <param-value>session</param-value>   
      </init-param>    
</filter>     
<filter-mapping>     
<filter-name>CacheFilter</filter-name>   
<!-对所有shtml页面内容进行缓存-->     
<url-pattern>*.shtml</url-pattern>    
</filter-mapping>

4.分布式缓存(没有研究)

小结

1、清除缓存:

<!-- refresh为true将会导致缓存的内容过期而被清除,简单地说,该属性为true用于清除缓存 -->
<!-- <oscache:flush scope="application"/>清除application范围内的所有缓存;
<oscache:flush scope="session" key="huhui"/>       #清除session范围内的key为huhui的缓存
<oscache:flush scope="application" group="hu"/>    #清除application范围内组名为hu内的所有缓存 -->
<%@ page language="java" pageEncoding="UTF-8"%>
<%@taglib uri="http://www.opensymphony.com/oscache" prefix="oscache" %>
<oscache:flush scope="applocation"/>               #缓存已清除

2、局部缓存:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.opensymphony.com/oscache" prefix="oscache" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
  </head>
  <body><!-- 这是局部缓存 -->
  <oscache:cache key="huhui" scope="session" time="15" refresh="${param.refresh }">
  <!-- 是使用Map对象来存储缓存的,默认的key是uri路径,如:/oscache/index.jsp,也可以指定它的key -->
  <!-- 缓存默认存放在application范围,缓存时间默认为3600秒,即1小时 -->
    <div><%=new Date() %></div>
  </oscache:cache>
  当前时间:<%=new Date() %>
  </body>
</html>

3、全局缓存:web.xml

<!-- 设置页面的全局缓存 -->
  <filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>7200</param-value>
</init-param>
<init-param>
    <param-name>scope</param-name>
    <param-value>application</param-value>
</init-param>
   </filter>
   <filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>/hotel/list.shtml</url-pattern>
</filter-mapping>

4、内存缓存/硬盘缓存推荐使用内存缓存,比硬盘缓存要快

oscache.properties
#指定是否使用内存缓存,默认值为true,即使用内存缓存
cache.memory=true
#指定缓存的容量,默认的容量是无限的
cache.capacity=10000
#如果要使用硬盘缓存,可以这样设置:
cache.memory=false
#指定缓存保存的路径
cache.path=/opt/springmvc/cache
#用于设置持久化的类
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener

Refer:
http://blog.chinaunix.net/uid-122937-id-142910.html
http://blog.csdn.net/zhifeng172/article/details/7608682
http://blog.csdn.net/orclight/article/category/1331444

posted @ 2013-04-05 13:35  花儿笑弯了腰  阅读(3833)  评论(0编辑  收藏  举报