Ehcache 集群示例系列1:RMI manual方式(手动发现方式)

来源:互联网 发布:盛一伦非凡搭档知乎 编辑:程序博客网 时间:2024/06/06 12:53

因系统要实现集群功能,在摸着石头过河一段时间后,利用ehcache实现集群效果,特记下来.一供自己总结知识要点,二供有此需要的网友一些示例.

共有:RMI 自动发现,手动发现,JGroups UDP协议,JGroups TCP协议四种具体的实现.并会给出一些自己在处理过程中遇到的常见错误.


一、类包

 commons-collections-3.2.1.jar,commons-lang3-3.1.jar,,ehcache-2.7.3.jar,ehcache-jgroups3replication-1.7.4.jar,jgroups-3.2.12.Final.jar,log4j-1.2.16.jar,slf4j-api-1.7.5.jar,slf4j-log4j12-1.7.5.jar

二、计算机节点和源码

示例中有两台计算机,ip分别用192.168.0.200,192.168.0.201。分别简称:200计算机,201计算机。

在200计算机上运行的java主类名为:EhcacheClusterRMIManualIP_200,201计算机上运行的主类为:EhcacheClusterRMIManualIP_201

这两个类不同处理是使用了不同的配置文件。

EhcacheClusterRMIManualIP_200 继承BaseCacheManager 中的main方法如下:

public static void main(String[] args) throws UnknownHostException, InterruptedException {EhcacheClusterRMIManualIP_200 clusterA = new EhcacheClusterRMIManualIP_200();String ehcacheConfigFile = null;if (args.length == 1) {ehcacheConfigFile = args[0];} else {ehcacheConfigFile = "EhcacheClusterRMIManualIP_200.xml";}URL configUrl = clusterA.setEhcacheConfig(ehcacheConfigFile);clusterA.createMessage(configUrl, 2);}

对应的配置文件:EhcacheClusterRMIManualIP_200.xml内容为:

<?xml version="1.0" encoding="gbk"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"><diskStore path="java.io.tmpdir" /><cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual,rmiUrls=//192.168.1.201:4567/replicationCache1|//192.168.1.201:4567/replicationCache2" /><!-- 使用此配置文件的类:EhcacheClusterRMIManualIP_200,运行此类的计算机ip为:192.168.0.200,所以hostName=192.168.0.200,rmiUrl=另一台计算机节点的ip的要同步的节点名 --><cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="hostName=192.168.1.200,port=4567,socketTimeoutMillis=2000"propertySeparator="," /><defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false" /><cache name="replicationCache1" maxElementsInMemory="10000" eternal="false" overflowToDisk="false" timeToIdleSeconds="1800" timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LFU"><cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true,replicatePuts=true,replicatePutsViaCopy=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true,asynchronousReplicationIntervalMillis=200"propertySeparator="," /><bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" /></cache><cache name="replicationCache2" maxElementsInMemory="10000" eternal="false" overflowToDisk="false" timeToIdleSeconds="1800" timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LFU"><cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true,replicatePuts=true,                            replicatePutsViaCopy=true, replicateUpdates=true,                            replicateUpdatesViaCopy=true, replicateRemovals=true,                            asynchronousReplicationIntervalMillis=200"propertySeparator="," /><bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" /></cache><cache name="cache3" maxElementsInMemory="10000" eternal="false" overflowToDisk="false" timeToIdleSeconds="1800" timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LFU"></cache></ehcache>


其中节点cache3不进行集群.

类BaseCacheManager:内容如下:

package com.ehUtils;import java.net.Inet4Address;import java.net.Inet6Address;import java.net.InetAddress;import java.net.URL;import java.net.UnknownHostException;import java.util.List;import net.sf.ehcache.Cache;import net.sf.ehcache.CacheManager;import net.sf.ehcache.Element;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * 生成并读取缓存key *  * @author XXX 2013-9-24 *  */public class BaseCacheManager {private final static Logger LOG = LoggerFactory.getLogger(BaseCacheManager.class);/** * 获取配置文件URL *  * @param classPathFile *            在src目录下 * @return */public URL setEhcacheConfig(String classPathFile) {ClassLoader cl = Thread.currentThread().getContextClassLoader();LOG.info("配置文件路径:{} ", classPathFile);URL url = cl.getResource(classPathFile);return url;}/** *  * @param ehcacheURL *            ehcache配置文件的URL * @param putSecond *            间隔多少秒存新值(可理解为刷屏) * @throws UnknownHostException * @throws InterruptedException */@SuppressWarnings("rawtypes")public void createMessage(URL ehcacheURL, int putSecond) throws UnknownHostException, InterruptedException {String localhostIp = InetAddress.getLocalHost().getHostAddress();LOG.info("当前计算机IP:{}", localhostIp);LOG.info("ip4地址:{},ip6地址:{}", Inet4Address.getLocalHost().getHostAddress(), Inet6Address.getLocalHost().getHostAddress());CacheManager cm = new CacheManager(ehcacheURL);String[] cacheNames = cm.getCacheNames();LOG.info("获取cache数量:{}", cacheNames.length);if (cacheNames.length > 0) {int seq = 0;while (true) {Thread.sleep(putSecond * 1000);LOG.info("循环所有的cache\n");for (String name : cacheNames) {Cache cache = cm.getCache(name);cache.put(new Element(localhostIp, seq++));List keys = cache.getKeys();StringBuilder kv = new StringBuilder();kv.append("{ ");for (Object eleName : keys) {Element ele = cache.get(eleName);kv.append(ele.getObjectKey()).append(":").append(ele.getObjectValue()).append(",");}kv.delete(kv.length() - 1, kv.length());kv.append("}");LOG.info("缓存name={},内容={}\n", name, kv.toString());kv.delete(0, kv.length());}}}}}

最终结构如下:


三、打包和运行

并EhcacheClusterRMIManualIP_200和EhcacheClusterRMIManualIP_201分别打包成可执行的jar,并分别在200计算机和201计算机上运行。

效果图中,因为是先在200计算机上运行EhcacheClusterRMIManualIP_200,所以同步时数值为99时201计算机上的同步数据才是0.key值分别为ip,value为一个序列的数值.其中cache3没有被同步,因为xml配置中没有设置为集群同步.

效果图:



项目已经打包,下载地址http://download.csdn.net/detail/yuan_little/6313999

需要将EhcacheClusterRMIManualIP_200(打包为200.jar)和EhcacheClusterRMIManualIP_201(打包为201.jar)打包成可执行的jar.运行的计算机修改ip地址为:192.168.0.200,并运行相应的200.jar,同时将运行201.jar的计算机ip也修改为192.168.0.201即可.

如果不想修改ip也可以修改xml配置文件.

可能出现的错误情况有:计算机不使用IPv4,此时要修改

在java 时使用ipv4,-Djava.net.preferIPv4Stack=true或在程序时使用system.setProperty("java.net.preferIPv4Stack","true");

另一种错误情况,在一台计算机中用eclipse直接运行一个类,在另一个计算机上运行打包好的jar,也可能出现不同步的情况.最好两台计算机都采用同一种方式来运行程序.如同时为jar或同时为eclipse运行.

四、下一篇RMI自动发现,ehcache RMI automic

原创粉丝点击