项目进入了后期阶段,发现了不少的性能问题,其中有部分领域对象在应用的某些阶段相对稳定,于是准备采用cache,减少对象构建次数,减少数据库访问次数,有针对性地改善性能问题。
using springmodules-cache的主要原因是其屏蔽了各个不同cache产品的接口差异性,提供了一致的编程模型,已经实现adapter的包括: EHCache, JBoss Cache, Java Caching System (JCS) and OSCache。
由于我们的项目已经使用了spring2.0,要引入oscache,需要做的工作如下:
-
需要的jar包括:jgroups-all.jar,oscache-2.3.2.jar,spring-modules-cache.jar,spring.jar,commons-logging.jar,jakarta-oro.jar.
-
增加了ArgumentsCacheKeyGenerator类,实现org.springmodules.cache.key.CacheKeyGenerator接口。不使用sm自带的hashcodecachekeygenerator原因是,想自己能够在其它模块手动生成cacheKey,以便主动refresh cache。java 代码
- import java.io.Serializable;
- import org.aopalliance.intercept.MethodInvocation;
- import org.springmodules.cache.key.CacheKeyGenerator;
- public class ArgumentsCacheKeyGenerator implements CacheKeyGenerator {
- private String prefix="";
- public Serializable generateKey(MethodInvocation mi) {
- // TODO Auto-generated method stub
- StringBuffer sb = new StringBuffer();
- sb.append(this.getPrefix()).append('_');
- Object[] args = mi.getArguments();
- for( int i=0; i
- sb.append(args[i]);
- }
- return sb.toString();
- }
- public String getPrefix() {
- return prefix;
- }
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
- }
-
增加了oscache_config.properties,cache容量为100个对象,调度算法为LRU。java 代码
- # 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.
- #
- cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCache
- # cache.algorithm=com.opensymphony.oscache.base.algorithm.FIFOCache
- # cache.algorithm=com.opensymphony.oscache.base.algorithm.UnlimitedCache
- # 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.capacity=100
- # 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
- # 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.
- #
- # cache.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:
- # cache.path=/opt/myapp/cache
- #
- # cache.path=c:\\app\\cache
- # 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 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
-
增加了cacheContext.xml,spirng中cache的配置文件.xml 代码
-
- class="org.springmodules.cache.provider.oscache.OsCacheManagerFactoryBean">
<bean id="cacheProviderFacade" - class="org.springmodules.cache.provider.oscache.OsCacheFacade">
- <property name="cacheManager" ref="cacheManager" />
- bean>
- <bean id="chinatechKeyGenerator" class="cache.key.ArgumentsCacheKeyGenerator" >
- <property name="prefix">
- <value>CHINATECHvalue>
- property>
- bean>
-
修改applicationContext.xmlxml 代码
- <bean id="tc2"
- class="org.springmodules.cache.interceptor.proxy.CacheProxyFactoryBean">
- <property name="cacheProviderFacade" ref="cacheProviderFacade" />
- <property name="cacheKeyGenerator" ref="chinatechKeyGenerator" />
- <property name="cachingModels">
- <props>
- <prop key="get*">refreshPeriod=600;groups=CHINATECHprop>
- props>
- property>
- <property name="flushingModels">
- <props>
- <prop key="update*">groups=CHINATECHprop>
- props>
- property>
- <property name="target" ref="tc2Target" />
- bean>
-
修改web.xml,增加cacheContext.xml初始化spring配置。
springmodules站点:springmodules.dev.java.net/
oscache站点:www.opensymphony.com/oscache