关于ehcache:84springboot-EhCache-集群一rmi-手动发现

ehcache 集群配置: server1(192.168.1.6): <?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false"> <!--超过大小后长久化磁盘地位--> <diskStore path="java.io.tmpdir"/> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual, rmiUrls=//192.168.1.5:40001/dcsCache"/> <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="hostName=192.168.1.6,port=40001, socketTimeoutMillis=2000"/> <!-- default cache --> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false"/> <!--自定义缓存配置--> <cache name="dcsCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true"/> <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" /> </cache></ehcache>server2(192.168.1.5): <?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false"> <!--超过大小后长久化磁盘地位--> <diskStore path="java.io.tmpdir"/> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual, rmiUrls=//192.168.1.6:40001/dcsCache"/> <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="hostName=192.168.1.5,port=40001, socketTimeoutMillis=2000"/> <!-- default cache --> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false"/> <!--自定义缓存配置--> <cache name="dcsCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true"/> <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" /> </cache></ehcache>application.yml server: port: 8082 servlet: context-path: /spring: devtools: restart: enabled: false cache: jcache: config: ehcache.xml测试管制类: package com.example.demo1125;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;@Controller@RequestMapping("/dcs/ec")public class EhcacheDcsController { private static final Logger logger = LoggerFactory.getLogger(EhcacheDcsController.class); @RequestMapping(value = "save") @Cacheable(value="dcsCache",key="#value") @ResponseBody public Object save(String value) { logger.info("logger:/dcs/ec/save...."+value); System.out.println("/dcs/ec/save...."+value); return value; } @RequestMapping(value="del") @CacheEvict(value="dcsCache",key="#value",beforeInvocation=true) @ResponseBody public String del(String value){ logger.info("logger:delete cache key...."+value); System.out.println("delete cache key:"+value); return "delete cache key:"+value; }}Demo1125Application: ...

October 17, 2022 · 2 min · jiezi

关于ehcache:大厂都在用EhCache它到底比Redis强在哪里

故事背景随着硬件价格的走低,大家对硬件的依赖越来越高。甚至据说,代码不重要,不行就加机器呗。比方缓存的应用,通常有基于虚拟机内存、基于磁盘存储、基于中间件(Redis内存)等形式,咱们都晓得,最适宜的才是最好的,但实际中,往往是动不动就间接上Redis。 那么,Redis肯定是最好的抉择吗?单不说对内存的要求,从效率和性能上来说,也未必是最优的。所以,不同的场景应用不同的缓存策略才是高手应该谋求的。 这篇文章就带大家意识除Redis之外的另一种缓存框架:EhCache。之所以要写写,也是因为我的项目中使用了此框架,同时又遇到点问题,于是决定深入研究一下。钻研之后,发现还真有点意思~ EhCache简介EhCache是一个纯Java的过程内缓存框架,具备疾速、精干的特点。留神的这里的关键字过程,基于过程的缓存直觉通知咱们效率必定要高一些,因为它间接在过程之内进行操作,但不同利用之间缓存的共享可能就会有问题。 EhCache是Hibernate中默认的CacheProvider,Spring Boot也对其进行了反对,Spring中提供的缓存形象也反对对EhCache缓存框架的绑定,而且反对基于注解的形式来应用。因而,EhCache是一款被宽泛应用的基于Java的高速缓存框架,应用起来也十分不便。 EhCache提供了多种缓存策略,次要分为内存和磁盘两级,是一款面向通用缓存、Java EE和轻量级容器的缓存框架。 EhCache的特点简略说一下该框架的特点: 简略、疾速,领有多种缓存策略;缓存数据有两级:内存和磁盘,无需放心容量问题;缓存数据会在虚拟机重启的过程中写入磁盘;能够通过RMI、可插入API等形式进行分布式缓存;具备缓存和缓存管理器的侦听接口;反对多缓存管理器实例,以及一个实例的多个缓存区域,并提供Hibernate的缓存实现;EhCache能够独自应用,但通常会与Mybatis、Shiro等三方类库联合应用。自己我的项目中应用EhCache就是联合Shiro来应用的。 除了长处,EhCache也还有一些毛病。比方,十分占用磁盘空间,这是因为DiskCache的算法简略,只是对元素间接追加存储。这样尽管能够提高效率,但在应用频繁的零碎中,磁盘很快会满。 另外就是不能保障数据安全,当然忽然kill掉Java过程时,可能会产生抵触。EhCache解决抵触的办法是重建Cache,这对Cache数据须要放弃时可能会产生影响。Cache只是简略的减速,不能保证数据的平安。 EhCache与RedisEhCache间接在JVM中进行缓存,速度快,效率高。与Redis相比,操作简略、易用、高效,尽管EhCache也提供有缓存共享的计划,但对分布式集群的反对不太好,缓存共享实现麻烦。 Redis是通过Socket拜访到缓存服务,效率比EhCache低,比数据库要快很多,解决集群和分布式缓存不便,有成熟的计划。 所以,如果是单体利用,或对缓存拜访要求很高,可思考采纳EhCache;如果是大型零碎,存在缓存共享、分布式部署、缓存内容很大时,则倡议采纳Redis。 EhCache架构图看一下EhCache的架构图,大略理解一下它由几局部组成。 Cache Replication局部提供了缓存复制的机制,用于分布式环境。EhCache最后是独立的本地缓存框架组件,在前期的倒退中,联合Terracotta服务阵列模型,能够反对分布式缓存集群,次要有RMI、JGroups、JMS和Cache Server等传播方式进行节点间通信。 In-process APIs则提供了基于JSR、JMX等规范的反对,可能较好的兼容和移植,同时对各类对象有较欠缺的监控管理机制。 Network APIs则对外提供了基于RESTful API、JMS API、Cache Server等形式的反对。 在应用过程中,须要关注的外围局部便是两头的Core局部了。它蕴含了外围的API和概念: CacheManager:缓存管理器,能够通过单例或者多例的形式创立,也是Ehcache的入口类。Cache:每个CacheManager能够治理多个Cache,每个Cache能够采纳hash的形式治理多个Element。所有cache都实现了Ehcache接口;Element:单条缓存数据的组成单位,用于寄存真正缓存内容的。三者的治理能够用下图示意: 缓存过期策略在架构图中还能够看到Memory Store LRU、Memory Store LFU、Memory Store FIFO等内存存储算法。也就是当缓存占用空间靠近临界值时,会采纳下面的淘汰策略来清理掉一部分数据。 EhCache提供了三种淘汰算法: FIFO:First In First Out,先进先出。判断被存储的工夫,离目前最远的数据优先被淘汰。LRU:Least Recently Used,最近起码应用。判断最近被应用的工夫,目前最远的数据优先被淘汰。LFU:Least Frequently Used,最不常常应用。在一段时间内,数据被应用次数起码的,优先被淘汰。Ehcache采纳的是懒淘汰机制,每次往缓存放入数据时,都会存一个工夫,在读取时要和设置的工夫做TTL比拟来判断是否过期。 EhCache实战解析理解了下面的基础知识之后,来试验一下EhCache如何应用。其中EhCache2.x和EhCache3.x的应用差距较大。 这里采纳比拟新的3.9.6版本,不同的版本在API的应用上会有所差别。 基于API应用EhCacheEhCache提供了基于API和xml两种模式创立CacheManger和Cache。先来看基于API的模式: 在pom文件中引入EhCache依赖: <dependency> <groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> <version>3.9.6</version></dependency> 创立并应用的代码如下: public class EhCacheTest { @Test public void test() { // 1、先创立一个CacheManagerBuilder; // 2、应用CacheManagerBuilder创立一个预配置(pre-configured)缓存:第一个参数为别名,第二个参数用来配置Cache; // 3、build办法构建并初始化;build中true参数示意进行初始化。 CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() .withCache("preConfigured", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(100)).build()) .build(true); // 取回在设定的pre-configured,对于key和value值类型,要求是类型平安的,否则将抛出ClassCastException异样。 Cache<Long, String> preConfigured = cacheManager.getCache("preConfigured", Long.class, String.class); System.out.println("从缓存中获取key为preConfigured:" + preConfigured); // 依据需要,通过CacheManager创立出新的Cache。实例化和残缺实例化的Cache将通过CacheManager.getCache API返回。 Cache<Long, String> myCache = cacheManager.createCache("myCache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(100)).build()); // 应用put办法存储数据 myCache.put(1L, "da one!"); // 应用get办法获取数据 String value = myCache.get(1L); System.out.println("从缓存中获取key为1L:" + value); // close办法将开释CacheManager所治理的缓存资源 cacheManager.close(); }}上述代码基于API的模式演示了如何创立CacheManager及Cache,并对Cache进行设置和获取。 ...

December 15, 2021 · 2 min · jiezi