Flex3,Struts2,Hibernate3,Spring2,UML,Oracle,mysql,tomcat,compass,lucene
2006年8月19日 #
Opensymphony ( 中文:open交响乐)(http://www.opensymphony.com)是一个很好提供开源项目的组织。同Jakarta(中文:雅加达(印度尼西亚首都))(http://jakarta.apache.org/) 相比,这里的组件(Component)更多的是精致小巧的设计,它们尤以简单易用和可插拔的灵活性见长。OSCache:J2EE Caching机制。它主要用于
三个方面。在JSP Caching、Request Caching方面,OSCache能够解决动态网站的基本问题:缓存动态内容、缓存二进制内容、错误包容。在General-Purpose Cache方面,在Java应用中通过调用OSCache的API来缓存任意的Java对象, hibernate从 2.0开始对其也有支持。 OSCache标记库是一种开创性的JSP定制标记应用,提供了在现有JSP页面之内实现快速内存缓冲的功能。虽然已经有一些供应商在提供各种形式的缓存产品,但是,它们都属于面向特定供应商的产品。OSCache能够在任何JSP 1.2兼容的服务器上运行,它不仅能够为所有用户缓冲现有JSP代码块,而且能够以用户为单位进行缓冲。OSCache还包含一些提高可伸缩性的高级特性,比如:
等等。
网上对OSCache的介绍大多是关于JSP Caching、Request Caching方面的,对任意java对象的缓冲大多数人选择了JCS。由于种种原因,hibernate 2.0 放弃了对 JCS 的支持,所以才引起了我对 OSCache 的关注,下面是我参考 hibernate 的源码对 OSCache 做的简单封装 代码内容/** Cache.java */
/** OSCache.java */
/** CacheManager.java */
OSCache是一个工业级的J2EE缓存实现。它可以缓存 :
等正文开始 。。。
为了减少与数据库通信 来提高应用的性能,我们在Hibernate中使用了分布式缓存:OSCache。
Oscache是得到了广泛使用的开源 Cache 实现(Hibernate中对它提供了支持),它基于更加可靠高效的设计,最重要的是,新版本的OSCache已经支持集群分布式。如果系统需要在部署在集群中,或者需要部署在多机负载均衡模式的环境中来获取更高性能,那么 OSCache将是不二之选。
我们知道为了实现分布式环境下消息的通知,目前两种比较流行的做法是使用 :
这两种方式都在底层实现了广播发布消息。 由于JGroups可以提供可靠的广播通信.所以我们准备采用JGroups。一、环境说明
JavaGroups ConfigurationJust make sure you have jgroups-all.jar file in your classpath (for a webapp put it in WEB-INF/lib), and add the JavaGroups broadcasting listener to your oscache.properties file like this: cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JavaGroupsBroadcastingListener
In most cases, that's it! OSCache will now broadcast any cache flush events across the LAN. The jgroups-all.jar library is not included with the binary distribution due to its size, however you can obtain it either by downloading the full OSCache distribution, or by visiting the JavaGroups website.
If you want to run more than one OSCache cluster on the same LAN, you will need to use different multicast IP addresses. This allows the caches to exist in separate multicast groups and therefore not interfere with each other. The IP to use can be specified in your oscache.properties file by the cache.cluster.multicast.ip property. The default value is 231.12.21.132, however you can use any class D IP address. Class D address fall in the range 224.0.0.0 through 239.255.255.255.
If you need more control over the multicast configuration (eg setting network timeout or time-to-live values), you can use the cache.cluster.properties configuration property. Use this instead of the cache.cluster.multicast.ip property. The default value is:
UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;\mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\PING(timeout=2000;num_initial_members=3):\MERGE2(min_interval=5000;max_interval=10000):\FD_SOCK:VERIFY_SUSPECT(timeout=1500):\pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\UNICAST(timeout=300,600,1200,2400):\pbcast.STABLE(desired_avg_gossip=20000):\FRAG(frag_size=8096;down_thread=false;up_thread=false):\pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)
See the JavaGroups site for more information. In particular, look at the documentation of Channels in the User's Guide.
三、我在应用中使用的 OSCache.properties:
# CACHE IN MEMORY## If you want to disable memory caching, just uncomment this line.## 不使用内存 cache.memory=false
# CACHE KEY## This is the key that will be used to store the cache in the application# and session scope.## If you want to set the cache key to anything other than the default# uncomment this line and change the cache.key## cache.key=__oscache_cache
# USE HOST DOMAIN NAME IN KEY## Servers for multiple host domains may wish to add host name info to# the generation of the key. If this is true, then uncomment the# following line.## cache.use.host.domain.in.key=true
# CACHE LISTENERS## These hook OSCache events and perform various actions such as logging# cache hits and misses, or broadcasting to other cache instances across a cluster.# See the documentation for further information.## cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JMSBroadcastingListener, \# com.opensymphony.oscache.extra.CacheEntryEventListenerImpl, \# com.opensymphony.oscache.extra.CacheMapAccessEventListenerImpl, \# com.opensymphony.oscache.extra.ScopeEventListenerImpl# 使用 JavaGroups 来实现监听广播式缓存cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JavaGroupsBroadcastingListener
# CACHE PERSISTENCE CLASS## Specify the class to use for persistence. If you use the supplied DiskPersistenceListener,# don't forget to supply the cache.path property to specify the location of the cache# directory.# # If a persistence class is not specified, OSCache will use memory caching only.## 启动硬盘持久化 Cachecache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
# CACHE OVERFLOW PERSISTENCE# Use persistent cache in overflow or not. The default value is false, which means# the persistent cache will be used at all times for every entry. true is the recommended setting.## cache.persistence.overflow.only=true
# CACHE DIRECTORY## This is the directory on disk where caches will be stored by the DiskPersistenceListener.# it will be created if it doesn't already exist. Remember that OSCache must have# write permission to this directory.## Note: for Windows machines, this needs \ to be escaped# ie Windows:# cache.path=c:\\myapp\\cache# or *ix:
# 在Linux下的Cache存放路径 cache.path=/data/jsp/boss.21cn.com/bossimpls/cache/bossuud## cache.path=c:\\app\\cache
# CACHE ALGORITHM## Default cache algorithm to use. Note that in order to use an algorithm# the cache size must also be specified. If the cache size is not specified,# the cache algorithm will be Unlimited cache.#
#使用LRU运算算法,把最少使用的Cache剔除出去 cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCache# cache.algorithm=com.opensymphony.oscache.base.algorithm.FIFOCache# cache.algorithm=com.opensymphony.oscache.base.algorithm.UnlimitedCache
# THREAD BLOCKING BEHAVIOR## When a request is made for a stale cache entry, it is possible that another thread is already# in the process of rebuilding that entry. This setting specifies how OSCache handles the# subsequent 'non-building' threads. The default behaviour (cache.blocking=false) is to serve# the old content to subsequent threads until the cache entry has been updated. This provides# the best performance (at the cost of serving slightly stale data). When blocking is enabled,# threads will instead block until the new cache entry is ready to be served. Once the new entry# is put in the cache the blocked threads will be restarted and given the new entry.# Note that even if blocking is disabled, when there is no stale data available to be served# threads will block until the data is added to the cache by the thread that is responsible# for building the data.## cache.blocking=false
# CACHE SIZE## Default cache size in number of items. If a size is specified but not# an algorithm, the cache algorithm used will be LRUCache.#
#这个值设得够大了,就是Cache的容量项目个数 cache.capacity=100000000
# CACHE UNLIMITED DISK# Use unlimited disk cache or not. The default value is false, which means# the disk cache will be limited in size to the value specified by cache.capacity.#
#不使用无限硬盘空间 cache.unlimited.disk=false
# JMS CLUSTER PROPERTIES## Configuration properties for JMS clustering. See the clustering documentation# for more information on these settings.##cache.cluster.jms.topic.factory=java:comp/env/jms/TopicConnectionFactory#cache.cluster.jms.topic.name=java:comp/env/jms/OSCacheTopic#cache.cluster.jms.node.name=node1
# JAVAGROUPS CLUSTER PROPERTIES## Configuration properites for the JavaGroups clustering. Only one of these# should be specified. Default values (as shown below) will be used if niether# property is set. See the clustering documentation and the JavaGroups project# (www.javagroups.com) for more information on these settings.#cache.cluster.properties=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;\mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\PING(timeout=2000;num_initial_members=3):\MERGE2(min_interval=5000;max_interval=10000):\FD_SOCK:VERIFY_SUSPECT(timeout=1500):\pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\UNICAST(timeout=300,600,1200,2400):\pbcast.STABLE(desired_avg_gossip=20000):\FRAG(frag_size=8096;down_thread=false;up_thread=false):\pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)cache.cluster.multicast.ip=231.12.21.132
关于作者
网名:润名E-mail: winsonhrh@gmail.com现从事于 21cn 公司,从事 J2EE 架构设计,有四年 J2EE工作经验。善长于对 Open Source Framework的技术整合开发和各种应用服务器的调优。
文章摘要Cache是一种用于提高系统响应速度、改善系统运行性能的技术。尤其是在Web应用中,通过缓存页面的输出结果,可以很显著的改善系统运行性能。本文中作者给大家介绍一个实现J2EE框架中Web应用层缓存功能的开放源代码项目----OSCache。通过应用OSCache,我们不但可以实现通常的Cache功能,还能够改善系统的稳定性。它的最新版本是 :OSCache2.3
1 面临的问题1.1 需要处理的特殊动态内容在信息系统建设过程中我们通常会遇到这样的问题:1. 基础数据的变更问题信息系统中需要处理的基础数据的内容短时间内是不会发生变化的,但是在一个相对长一些的时间里,它却可能是动态增加或者减少的。
举个例子:电子商务中关于送货区域的定义,可能短时间内不会发生变化,但是随着电子商务企业业务的扩大,系统中需要处理的送货区域就可能增加。所以我们的系统中不得不在每次向客户展示送货区域信息的时候都和数据库(假设送货区域信息保存在数据库中,这也是通常采用的处理方法)进行交互。
2. 统计报表(不仅限于统计报表)的问题一般来说,统计报表是一个周期性的工作,可能是半个月、一个月或者更长的时间才会需要更新一次,然而统计报表通常是图形显示或者是生成pdf、word、excel等格式的文件,这些图形内容、文件的生成通常需要消耗很多的系统资源,给系统运行造成很大的负担。
1.2 问题的共同点通过比较分析,不难发现这两类问题有一些共同点:
1.3 解决方法缓存技术可以帮助我们很好的解决这个问题:
1、缓存信息当上述的基础数据或者统计报表第一次被访问时,被处理的内容被当作动态信息,基础数库从数据库中获得,统计报表也会被生成符合要求的图形、文件,然后这些信息都会被放入缓存信息中。
2、响应信息由缓存提供当上述的基础数据或者统计报表继续被访问时,系统将会首先检查缓存信息中是否有对应的内容和我们设定的缓存规则,如果符合缓存信息存在而且符合缓存规则,给出的响应将来自于缓存信息,如果没有或者缓存信息已经不符合设定的要求,系统将重复上一步的动作。
很显然,上面的步骤2中,多数情况下,当用户请求到达时,被处理的内容将来自于缓存,所以大大的减少了与数据库的交互,或者不再需要为每个请求都生成一次报表图形或者文件,这部分工作的减少对于
是非常有益的。
2 OSCache简介 OSCache是OpenSymphony组织提供的一个J2EE架构中Web应用层的缓存技术实现组件,它的出现解决了我们面临的问题。 OSCache目前最新的稳定版本是2.3。
2.1 主要特征1. 兼容多种支持JSP的web服务器已经通过兼容测试的web服务器包括 :
2. 可选的缓存区
你可以使用内存、硬盘空间、同时使用内存和硬盘或者提供自己的其他资源(需要自己提供适配器)作为缓存区。
3. 灵活的缓存系统
OSCache支持对部分页面内容或者对页面级的响应内容进行缓存,编程者可以根据不同的需求、不同的环境选择不同的缓存级别。
4. 容错
在一般的web应用中,如果某个页面需要和数据库打交道,而当客户请求到达时,web应用和数据库之间无法进行交互,那么将返回给用户"系统出错"或者类似的提示信息,如果使用了OSCache的话,你可以使用缓存提供给用户,给自己赢得维护系统或者采取其他补救的时间。
5.其它特性包括对集群的支持、缓存主动刷新等特性,大家可以参考OpenSymphony网站上的其他资源获取更多的信息。
3 OSCache组件的安装OSCache是一个基于web应用的组件,他的安装工作主要是对web应用进行配置,大概的步骤如下:
1. 下载、解压缩OSCache
请到OSCache的主页http://www.opensymphony.com/oscache/download.html下载Oscache的最新版本,作者下载的是OSCache的最新稳定版本2.3。4 开始使用OSCache中的缓存组件OSCache中按照缓存范围的不同分为两种不同的方式:一种是缓存JSP页面中部分或者全部内容,一种是基于整个页面文件的缓存。
4.1 JSP部分内容缓存4.1.1 Cache-OSCache提供的缓存标签这是OSCache提供的标签库中最重要的一个标签,包括在标签中的内容将应用缓存机制进行处理,处理的方式将取决于编程者对cache标签属性的设置。
第一次请求到达时,标签中的内容被处理并且缓存起来,当下一个请求到达时,缓存系统会检查这部分内容的缓存是否已经失效,主要是以下几项:
如果符合上面四项中的任何一项,被缓存的内容视为已经失效,这时被缓存的内容将被重新处理并且返回处理过后的信息,如果被缓存的内容没有失效,那么返回给用户的将是缓存中的信息。
cache标签的属性说明:
key - 标识缓存内容的关键词。在指定的作用范围内必须是唯一的。默认的key是被访问页面的URI和后面的请求字符串。
scope - 缓存发生作用的范围,可以是application或者session
time - 缓存内容的时间段,单位是秒,默认是3600秒,也就是一个小时,如果设定一个负值,那么这部分被缓存的内容将永远不过期。
duration - 指定缓存内容失效的时间,是相对time的另一个选择,可以使用简单日期格式或者符合USO-8601的日期格式。如:duration='PT5M' duration='5s'等
refresh - false 或者true。如果refresh属性设置为true,不管其他的属性是否符合条件,这部分被缓存的内容都将被更新,这给编程者一种选择,决定什么时候必须刷新。
mode - 如果编程者不希望被缓存的内容增加到给用户的响应中,可以设置mode属性为"silent"
其它可用的属性还包括:
上面的这些属性可以单独使用,也可以根据需要组合使用,下面的例子将讲解这些常用属性的使用方式。
4.1.2 Cache标签实例分析:1. 最简单的cache标签用法
使用默认的关键字来标识cache内容,超时时间是默认的3600秒
2. 用自己指定的字符串标识缓存内容,并且设定作用范围为session。
3.动态设定key值,使用自己指定的time属性设定缓存内容的超时时间,使用动态refresh值决定是否强制内容刷新。
因为OSCache使用key值来标识缓存内容,使用相同的key值将会被认为使用相同的的缓存内容,所以使用动态的key值可以自由的根据不同的角色、不同的要求决定使用不同的缓存内容。
4. 设置time属性为负数使缓存内容永不过期
5. 使用duration属性设置超期时间
6. 使用mode属性使被缓存的内容不加入给客户的响应中
4.2 用CashFilter实现页面级缓存在OSCache组件中提供了一个CacheFilter用于实现页面级的缓存,主要用于对web应用中的某些动态页面进行缓存,尤其是那些需要生成pdf格式文件/报表、图片文件等的页面,不仅减少了数据库的交互、减少数据库服务器的压力,而且对于减少web服务器的性能消耗有很显著的效果。
这种功能的实现是通过在web.xml中进行配置来决定缓存哪一个或者一组页面,而且还可以设置缓存的相关属性,这种基于配置文件的实现方式对于J2EE来说应该是一种标准的实现方式了。
[注] 只有客户访问时返回http头信息中代码为200(也就是访问已经成功)的页面信息才能够被缓存
修改web.xml,增加如下内容,
1. 缓存单个文件
确定对/testContent.jsp页面进行缓存。
2. 缓存URL pattern
修改web.xml,增加如下内容,确定对*.jsp页面进行缓存。
3. 自己设定缓存属性
在页面级缓存的情况下,可以通过设置CacheFilter的初始属性来决定缓存的一些特性:time属性设置缓存的时间段,默认为3600秒,可以根据自己的需要只有的设置,而scope属性设置,默认为application,可选项包括application、session