首页 > 代码库 > Spring-ehcache RMI形式的分布式缓存配置

Spring-ehcache RMI形式的分布式缓存配置

ehcache所需jar:ehchache-core 和spring注解所需 spring-context

<dependency>
   <groupId>net.sf.ehcache</groupId>
   <artifactId>ehcache-core</artifactId>
   <version>2.6.6</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>4.2.7.RELEASE</version>
</dependency>


spring.xml文件中关于spring-ehcache.xml的引用说明

引入命名空间
  xmlns:cache="http://www.springframework.org/schema/cache"

注解使用cacheManager
<!-- ehcache config -->    
<cache:annotation-driven  cache-manager="cacheManager"/>  
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/>  
<!-- EhCache library setup -->  
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="classpath:spring/spring-ehcache.xml" p:shared="true"/>


spring-ehcache.xml文件文件头 该文件的命名可以自定义,只要在代码里引入即可

1】name 名称-可选,唯一。名字用于注解或区别Terracotta集群缓存。对于  
Terracotta集群缓存,缓存管理器的名字和缓存的名字的组合能够在Terracotta集群缓存中标志一个特定的缓存存储。
2】updateCheck 更新检查-一个可选的布尔值标志符,用于标志缓存管理器是否应该通过网络检查Ehcache的新版本。默认为true。  
3】dynamicConfig 动态配置 - 可选。用于关闭与缓存管理器相关的缓存的动态配置。默认为true,即动态配置为开启状态。动态配置的缓存可以根据缓存对象在运行状态改变自己的TTI,TTL和最大磁盘空间和内在容量  
4】monitoring 监控 - 可选。决定缓存管理器是否应该自动注册SampledCacheMBean到系统MBean服务器上。
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    monitoring="autodetect" dynamicConfig="true">
    
</ehcache>



<!-- cacheManagerPeerProviderFactory分布式缓存管理器提供者-->

propertySeparator     拆分上面properties属性的分隔符
peerDiscovery=manual    手动的缓存同步
peerDiscovery=automatic 广播式的缓存同步
rmiUrls                指的是手动侦测缓存地址,每一次当请求相应的缓存信息时,程序会先从配置的rmiUrls里去分别读取缓存,如果无该缓存信息,则生成缓存,存储在cacheManagerPeerListenerFactory所配置的地址和端口的对应的缓存里
                        地址与地址之间用|(竖线)来分割,url填写规则:
                        //(双斜杠)+cacheManagerPeerListenerFactory属性中配置的hostName+:(冒号)+端口+/(斜杠)+缓存属性名称
   一般rmiUrls地址信息里不包含自身cacheManagerPeerListenerFactory配置的地址
<cacheManagerPeerProviderFactory
   class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=manual, 
          rmiUrls=//127.0.0.1:40002/patientCache|//127.0.0.1:40002/menuCache|//127.0.0.1:40002/appCfgCache "
    propertySeparator="," />


<!-- cacheManagerPeerListenerFactory分布式缓存监听工厂-->

用于监听集群中的缓存复制信息,此处的端口信息必须cacheManagerPeerProviderFactory 中配置的端口一致,目前未本地的相关配置hostName=127.0.0.1 port=40002
备注:此处的端口号不是web工程的端口号,是一个自定义的未被占用的端口,本人自己试验的时候因为没经验误认为是web工程的端口,结果提示端口冲突
<cacheManagerPeerListenerFactory 
         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
          properties="hostName=127.0.0.1,port=40002,socketTimeoutMillis=2000" />


<!-- 具体缓存的配置-->

缓存属性解释:
     必须属性:
         name:设置缓存的名称,用于标志缓存,惟一
         maxElementsInMemory:在内存中最大的对象数量
         maxElementsOnDisk:在DiskStore中的最大对象数量,如为0,则没有限制
         eternal:设置元素是否永久的,如果为永久,则timeout忽略
         overflowToDisk:是否当memory中的数量达到限制后,保存到Disk
    可选的属性:
         timeToIdleSeconds:设置元素过期前的空闲时间
         timeToLiveSeconds:设置元素过期前的活动时间
         diskPersistent:是否disk store在虚拟机启动时持久化。默认为false
         diskExpiryThreadIntervalSeconds:运行disk终结线程的时间,默认为120秒
         memoryStoreEvictionPolicy:策略关于Eviction
    缓存子元素:
         cacheEventListenerFactory:注册相应的的缓存监听类,用于处理缓存事件,如put,remove,update,和expire
         bootstrapCacheLoaderFactory:指定相应的BootstrapCacheLoader,用于在初始化缓存,以及自动设置。
<!-- 缓存最长存在12小时后失效,如果12小时未访问,缓存也会失效 -->
 <cache name="patientCache" maxEntriesLocalHeap="10000" eternal="false"
        timeToIdleSeconds="43200" timeToLiveSeconds="43200"> 
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
            properties="replicateAsynchronously=false, replicatePuts=true,
                            replicatePutsViaCopy=true, replicateUpdates=true,
                            replicateUpdatesViaCopy=true, replicateRemovals=true" />
                            
 </cache>


读取/生成缓存@Cacheable

能够根据方法的请求参数对其结果进行缓存。即当重复使用相同参数调用方法的时候,方法本身不会被调用执行,即方法本身被略过了,取而代之的是方法的结果直接从缓存中找到并返回了。

value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name
key:缓存的key(保证唯一的参数),默认为空,既表示使用方法的参数类型及参数值作为key,支持SpEL
      缓存key还可以用如下规则组成,当我们要使用root作为key时,可以不用写root直接@Cache(key="caches[1].name")。因为他默认是使用#root的
     1.methodName   当前方法名        #root.methodName
     2.method      当前方法        #root.method.name
     3.target      当前被动用对象        #root.target
     4.targetClass   当前被调用对象        Class#root.targetClass
     5.args       当前方法参数组成的数组  #root.args[0]
     6.caches      当前被调用方法所使用的Cache   #root.caches[0],name
     7.方法参数     假设包含String型参数str      #str  
                               #p0代表方法的第一个参数
              假设包含HttpServletRequest型参数request  #request.getAttribute(‘usId32‘)  调用入参对象的相关包含参数的方法
              假设包含User型参数user             #user.usId   调用入参对象的无参方法可以直接用此形式
     8.字符串                                     ‘字符串内容‘                 
condition:触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL

JAVA代码示例

@Cacheable(value="http://www.mamicode.com/patientCache",key="#hosId+‘_‘+#request.getAttribute(‘usId32‘)+‘_‘+‘patientList‘" )
@RequestMapping(value = "/{hosId}/20004/005", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
@ResponseBody
public ResultVo listPats(@PathVariable Long hosId,HttpServletRequest request) {

}


删除缓存@CacheEvict

根据value 和key值来唯一找到缓存记录,并且清理缓存信息

value:缓存的位置,不能为空。
key:缓存的key,默认为空。
condition:触发的条件,只有满足条件的情况才会清楚缓存,默认为空,支持SpEL。
allEntries:true表示清除value中的全部缓存(可以理解为清空表),默认为false(删除单条数据)。
beforeInvocation:当我们设置为true时,Spring会在调用该方法之前进行缓存的清除。清除操作默认是在方法成功执行之后触发的。


JAVA代码示例

@CacheEvict(value="http://www.mamicode.com/patientCache",key="#hosId+‘_‘+#usId32+‘_‘+‘patientList‘")
@RequestMapping(value="http://www.mamicode.com/{hosId}/{usId32}/frushPatListCache",method=RequestMethod.POST,produces = "application/json;charset=UTF-8")
@ResponseBody
public void freashPatListCache(@PathVariable Long hosId,@PathVariable String usId32,HttpServletResponse response,HttpServletRequest request){
      LoggerUtil.debug(logger,  "【患者缓存信息清理frushPatListCache】清理某个用户的患者列表方法对应的缓存结构,进入方法体里面");
}


更新缓存@CachePut

它虽然也可以声明一个方法支持缓存,但它执行方法前是不会去检查缓存中是否存在之前执行过的结果,而是每次都执行该方法,并将执行结果放入指定缓存中。

value:缓存的位置,不能为空。
key:缓存的key,默认为空。
condition:触发的条件,只有满足条件的情况才会清楚缓存,默认为空,支持SpEL。


JAVA代码示例

@CachePut(value="http://www.mamicode.com/patientCache",key="#hosId+‘_‘+#usId32+‘_‘+‘patientList‘")
@RequestMapping(value="http://www.mamicode.com/{hosId}/{usId32}/frushPatListCache2",method=RequestMethod.POST,produces = "application/json;charset=UTF-8")
@ResponseBody
public void freashPatListCache2(@PathVariable Long hosId,@PathVariable String usId32,HttpServletResponse response,HttpServletRequest request){
    LoggerUtil.debug(logger,  "【患者缓存信息清理frushPatListCache】清理某个用户的患者列表方法对应的缓存结构,进入方法体里面");
}



参考资料

深入探讨在集群环境中使用 EhCache 缓存系统

http://www.ehcache.org/ehcache.xml译文

本文出自 “指尖疯客” 博客,请务必保留此出处http://tianyang10552.blog.51cto.com/7380722/1899550

Spring-ehcache RMI形式的分布式缓存配置