spring boot2.x分布式集成ehcache

学习资料:IBM BLOG、ehcache官网、分布式缓存博客

EhCache 从 1.7 版本开始,支持五种集群方案,分别是:Terracotta、RMI、JMS、JGroups和EhCache Server

下文主要记录了RMI的具体实现方式(模式内容介绍摘自IBM BLOG)。

目前只实现了手动配置(有坑),自动发现未实现,期待大神指点

RMI 集群模式

RMI 是 Java 的一种远程方法调用技术,是一种点对点的基于 Java 对象的通讯方式。EhCache 从 1.2 版本开始就支持 RMI 方式的缓存集群。在集群环境中 EhCache 所有缓存对象的键和值都必须是可序列化的,也就是必须实现 java.io.Serializable 接口,这点在其它集群方式下也是需要遵守的。

由于 RMI 是 Java 中内置支持的技术,因此使用 RMI 集群模式时,无需引入其它的 Jar 包,EhCache 本身就带有支持 RMI 集群的功能。使用 RMI 集群模式需要在 ehcache.xml 配置文件中定义 cacheManagerPeerProviderFactory 节点。采用 RMI 集群模式时,集群中的每个节点都是对等关系,并不存在主节点或者从节点的概念,因此节点间必须有一个机制能够互相认识对方,必须知道其它节点的信息,包括主机地址、端口号等。

EhCache 提供两种节点的发现方式:

  • 手动配置:手动配置方式要求在每个节点中配置其它所有节点的连接信息,一旦集群中的节点发生变化时,需要对缓存进行重新配置
  • 自动发现:每个节点上的配置信息都相同,大大方便了节点的部署,避免人为的错漏出现

引入pom文件


    org.springframework.boot
    spring-boot-starter-cache



    net.sf.ehcache
    ehcache

实现 CacheConfig类

package com.kexin.ehcache.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

/**
 * @Author KeXin
 * @Date 2019/6/20 下午5:58
 **/
@EnableCaching
@Configuration
public class CacheConfig {

    @Value("${common.properties.ehcache-xml-path}")
    //xml文件放在resource文件夹下对应的路径为:/ehcache-test.xml,我这里是将路径配置到了yml中
    private String ehcacheXmlPath;

    /**
     * ehcache 主要的管理器
     * @param bean
     * @return
     */
    @Bean(name = "appEhCacheCacheManager")
    public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean bean){
        return new EhCacheCacheManager (bean.getObject ());
    }

    /**
     * 据shared与否的设置,Spring分别通过CacheManager.create()或new CacheManager()方式来创建一个ehcacheManager.
     * @return
     */
    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean ();
        cacheManagerFactoryBean.setConfigLocation (new ClassPathResource(ehcacheXmlPath));
        cacheManagerFactoryBean.setShared (true);
        return cacheManagerFactoryBean;
    }
}

测试controller实现

package com.kexin.ehcache.controller;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Author KeXin
 * @Date 2019/06/20 下午6:17
 **/
@RestController
@RequestMapping("test")
public class TestController {
    @RequestMapping("/e-get")
    @Cacheable(value = "offLineCache", key = "#key")
    public String get(String key){
        System.out.println("未走echache");
        return key.hashCode()+"";
    }
}

手动配置实现

ehcache.xml



    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
        
        
    
        
        
    

 

自动发现配置实现

网上资料说把ehcache.xml中的cacheManagerPeerProviderFactory配置成如下,其中multicastGroupAddress为D类广播IP:

但是未实验成功

测试结果

先后启动两个application,端口分别为55300、55193

然后依此请求以下接口,观察控制台输出情况

  • localhost:55300/test/e-get?key=test
  • localhost:55193/test/e-get?key=test

但是有异常

Java RMI:rmi Connection refused to host: 127.0.0.1异常

解决方法:https://blog.csdn.net/chenchaofuck1/article/details/51558995

 

# 附录

1、获得本机内网ip并设置成环境变量

try {
    Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
    InetAddress ip;
    while (allNetInterfaces.hasMoreElements()) {
        NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
        if (!"en0".equals(netInterface.getName()) && !"eth0".equals(netInterface.getName())) {
            continue;
        }
        Enumeration addresses = netInterface.getInetAddresses();
        while (addresses.hasMoreElements()) {
            ip = (InetAddress) addresses.nextElement();
            if (ip instanceof Inet4Address) {
                System.out.println("本机的IP = " + ip.getHostAddress());
                System.setProperty("cdbLocalIp", ip.getHostAddress());
            }
        }
    }
} catch (SocketException e) {
    e.printStackTrace();
}

你可能感兴趣的:(数据库+缓存)