ehcache是一个开源的Java本地缓存框架,同时以replication的形式提供分布式缓存管理。这里介绍下使用RMI手动配置的方法在一个JVM里面启动多个CacheManager来实现分布式缓存。
这里配置3个CacheManager,由于只有一台机器,所以实在一个JVM里面使用3个CacheManager的方法来模拟分布式。
<?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" name="nodeA">
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//localhost:40002/cache1|//localhost:40003/cache1" />
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40001,
socketTimeoutMillis=2000" />
<cache name="cache1" maxEntriesLocalHeap="10" eternal="false"
timeToIdleSeconds="100" timeToLiveSeconds="100" overflowToDisk="false">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,
replicateUpdatesViaCopy=false, replicateRemovals=true " />
</cache>
</ehcache>
<?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" name="nodeB">
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//localhost:40001/cache1|//localhost:40003/cache1" />
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40002,
socketTimeoutMillis=2000" />
<cache name="cache1" maxEntriesLocalHeap="10" eternal="false"
timeToIdleSeconds="100" timeToLiveSeconds="100" overflowToDisk="false">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,
replicateUpdatesViaCopy=false, replicateRemovals=true " />
</cache>
</ehcache>
<?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" name="nodeC">
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//localhost:40001/cache1|//localhost:40002/cache1" />
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40003,
socketTimeoutMillis=2000" />
<cache name="cache1" maxEntriesLocalHeap="10" eternal="false"
timeToIdleSeconds="100" timeToLiveSeconds="100" overflowToDisk="false">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,
replicateUpdatesViaCopy=false, replicateRemovals=true " />
</cache>
</ehcache>
package com.suifengfei.learn.ehcachelearn.replication;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RmiReplication {
private final static Logger logger = LoggerFactory.getLogger(RmiReplication.class);
private CacheManager nodeA ;
private CacheManager nodeB ;
private CacheManager nodeC ;
public void setup(){
nodeA = CacheManager.newInstance("src/main/resources/ehcache-rmi-replication-nodeA.xml");
nodeB = CacheManager.newInstance("src/main/resources/ehcache-rmi-replication-nodeB.xml");
nodeC = CacheManager.newInstance("src/main/resources/ehcache-rmi-replication-nodeC.xml");
}
public void shutdown(){
if( null != nodeA ){
nodeA.shutdown();
}
if( null != nodeB ){
nodeB.shutdown();
}
if( null != nodeC ){
nodeC.shutdown();
}
}
public static void main(String[] args) {
RmiReplication rmiReplication = new RmiReplication();
rmiReplication.setup();
try {
rmiReplication.simpleTest();
} catch (InterruptedException e) {
e.printStackTrace();
}
rmiReplication.shutdown();
}
private void simpleTest() throws InterruptedException{
Cache cacheA1 = nodeA.getCache("cache1");
Cache cacheB1 = nodeB.getCache("cache1");
Cache cacheC1 = nodeC.getCache("cache1");
Element e1 = new Element("a", "hello") ;
cacheA1.put(e1);
Thread.sleep(2000);
Element e1_B = cacheB1.get("a");
if( null != e1_B ){
String e1V = (String)e1_B.getValue();
logger.info("e1 value from nodeB:" + e1V);
}
Element e1_C = cacheC1.get("a");
if( null != e1_C ){
String e1V = (String)e1_C.getValue();
logger.info("e1 value from nodeC:" + e1V);
}
}
}
[22 13:02:48,411 INFO ] [main] replication.RmiReplication - e1 value from nodeB:hello
[22 13:02:48,411 INFO ] [main] replication.RmiReplication - e1 value from nodeC:hello
在配置ehcache的时候,有一点需要注意,需要配置好ehcache元素的name属性,虽然这个属性是一个optinal的,我们看一下官方文档
CacheManager.newInstance(Configuration configuration) – Create a new CacheManager or return the existing one named in the configuration.
也就说每一个CacheManager都有一个name,如果不配置name属性的话,这个name会是一个相同的默认值,在测试代码中虽然nodeA,nodeB,nodeC加载了3个不同的配置,但是由于name都是相同的,返回的nodeB和nodeC其实和nodeA引用了相同的对象,在运行到缓存操作的时候,由于调用不到对方的RMI接口服务,会报错。
[22 13:08:44,148 DEBUG] [Replication Thread] distribution.ManualRMICacheManagerPeerProvider - Looking up rmiUrl //localhost:40002/cache1 through exception Connection refused to host: localhost; nested exception is:
java.net.ConnectException: Connection refused: connect. This may be normal if a node has gone offline. Or it may indicate network connectivity difficulties
java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
java.net.ConnectException: Connection refused: connect
通过下面的CachaManager的实现也可以看出来对于这个name的判断
private static CacheManager newInstance(Configuration configuration, String msg) throws CacheException {
synchronized (CacheManager.class) {
String name = configuration.getName();
if (name == null) {
name = DEFAULT_NAME;
}
CacheManager cacheManager = CACHE_MANAGERS_MAP.get(name);
if (cacheManager == null) {
LOG.debug(msg);
cacheManager = new CacheManager(configuration);
}
return cacheManager;
}
}
分享到:
相关推荐
Ehcache是一个流行的开源Java缓存库,广泛用于提高应用程序性能,通过存储数据在内存中,减少对数据库的访问次数。在分布式环境中,Ehcache能够跨多个节点共享数据,进一步提升系统的可扩展性和响应速度。本实例将...
在实现单个JVM内的缓存框架时,我们可以使用ConcurrentHashMap,它是一个线程安全的数据结构,适合在多线程环境下作为基础缓存容器。例如,SpringBoot中的简单MapCache实现就展示了如何通过这个数据结构实现存取删除...
本地缓存是指在应用程序内部的缓存组件,其最大优点是应用程序和缓存处于同一个进程内部,请求缓存非常快速,没有过多的网络开销等。在单应用不需要集群支持或者集群情况下各节点无需互相通知的场景下使用本地缓存较...
当我们谈论“Spring + Ehcache + Redis”两级缓存时,我们实际上是在讨论如何在Java环境中利用Spring框架来集成Ehcache作为本地缓存,并利用Redis作为分布式二级缓存,构建一个高效且可扩展的缓存解决方案。...
EhCache是一个纯Java的进程内缓存框架,具有快速、上手简单等特点,是Hibernate中默认的缓存提供方。 2、Hibernate缓存 Hibernate三级缓存机制简介: 一级缓存:基于Session级别分配一块缓存空间,缓存访问的对象...
Ehcache是一个开源的Java缓存库,广泛用于提高应用程序性能,通过存储数据副本来减少对数据库的访问。它提供了一级缓存和二级缓存的功能,尤其在大数据量和高并发场景下,能显著提升系统响应速度。在这个"Ehcache二...
1. **Terracotta服务器**: Ehcache通过集成Terracotta服务器,可以实现跨JVM的分布式缓存,提高多节点间的缓存共享和一致性。 2. **复制策略**: 分布式缓存中,当在一个节点上添加、更新或移除元素时,这些操作可以...
Ehcache 是一个广泛使用的开源 Java 缓存框架,它在处理大量数据的高性能应用中扮演着重要角色。Ehcache 提供了本地内存缓存、磁盘存储以及分布式缓存的能力,使得应用程序能够快速访问频繁使用的数据,从而提高整体...
**Ehcache** 是一个广泛使用的Java分布式内存缓存系统,它被设计用来提高应用程序的性能,通过存储经常访问的数据来减少对数据库的依赖。Ehcache_2.10.4版本是其在2015年的一个稳定版本,提供了丰富的功能和优化。这...
Spring Cloud Config是一个分布式配置中心,允许在单个JVM或多个JVM上运行的服务共享配置。每个服务从Config Server获取配置,这样就可以轻松地更新和管理所有服务的配置。 六、JVM内存管理 当在一个JVM中运行多个...
1. **高速缓存**:由于ehcache是在JVM虚拟机内部实现缓存,因此具有极高的访问速度。 2. **灵活性**:ehcache支持多种缓存策略,用户可以根据应用场景选择最适合的策略。 3. **缓存管理**:提供了丰富的API用于管理...
在代码示例中,我们看到一个典型的多级缓存访问流程:首先尝试从JVM堆缓存中获取数据,若未命中,则查询分布式缓存,最后再回溯到数据库。这种设计既利用了本地缓存的高速访问,也利用了分布式缓存的大容量存储,...
- 提供大内存支持:bigmemory-max是Ehcache的一个扩展,专门设计用于处理大数据量的场景,能够有效地利用JVM的大内存区域(如 PermGen 或 Metaspace)。 - Off-Heap存储:它允许将缓存数据存储在JVM堆外,避免了...
3. **分布式缓存**: 分布式缓存允许在多个JVM之间共享数据,Ehcache通过Terracotta服务器支持分布式缓存,适用于多节点集群环境。 **二、核心组件** 1. **Cache**: 缓存是Ehcache的基本单元,它包含一组键值对,并...
ehCache是一个开源的Java分布式缓存系统,它可以极大地提高应用程序的性能,特别是对于频繁访问但更新不频繁的数据。ehCache支持内存和磁盘存储,并且可以与JVM无缝集成,使得数据缓存变得简单易用。 结合Spring ...
总之,金融级分布式缓存平台的一致性设计是一个复杂而关键的任务,需要综合运用多种技术和策略,确保在高并发、分布式环境下的数据准确性和系统稳定性。通过理解并解决事务缓存一致性、并发乱序一致性、主从切换一致...
EhCache是一个高效且灵活的缓存框架,它在Java应用程序中被广泛使用,尤其是在处理大量数据时,能够显著提高性能。作为纯Java实现,它可以在任何Java运行环境中无缝集成,无需依赖特定的操作系统或硬件平台。EhCache...
2. **Ehcache**:Ehcache 是一个基于内存的缓存解决方案,支持在 JVM 内部缓存数据,以及可选的分布式缓存功能。它能快速存储和检索数据,提高应用程序性能,尤其适用于高并发场景。 3. **整合 Hibernate 和 ...