二)spring 集成 ehcache jgroups 集群

依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>
        <!-- org.springframework.cache.ehcache.EhCacheCacheManager -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>
        <!-- ehcache -->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.6.11</version>
        </dependency>
        <!-- 缓存集群同步(jgroups) -->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-jgroupsreplication</artifactId>
            <version>1.7</version>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.1.6.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

项目结构

│  pom.xml
│
├─src
│  ├─main
│  │  ├─java
│  │  │  └─cn
│  │  │      └─zno
│  │  │              Person.java
│  │  │              PersonService.java
│  │  │              PersonServiceImpl.java
│  │  │
│  │  └─resources
│  │          applicationContext-Ehcache.xml
│  │          ehcache.xml
│  │
│  └─test
│      ├─java
│      │  └─ehcache
│      │          TestEhcache.java
│      │
│      └─resources

applicationContext-Ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
    <context:annotation-config />
    <context:component-scan base-package="cn.zno" />

    <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
    <cache:annotation-driven cache-manager="cacheManager" />

    <!-- 声明cacheManager -->
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
        p:cacheManager-ref="cacheManagerFactory" />

    <!-- cacheManager工厂类,指定ehcache.xml的位置 -->
    <bean id="cacheManagerFactory"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
        p:configLocation="classpath:ehcache.xml"
        p:shared="true" scope="singleton" />
</beans>

ehcache.xml (详细解释请看jgroups)

<?xml version="1.0" encoding="UTF-8"?>

<ehcache updateCheck="false" dynamicConfig="true"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

    <diskStore path="java.io.tmpdir" />

<!-- 
    UDP(
        mcast_addr:Multicast address to be used for discovery
        mcast_port:Multicast port for discovery packets. Default is 7555
        bind_port:Port for discovery packets
        ip_ttl:The time-to-live (TTL) for multicast datagram packets. Default is 8
        mcast_send_buf_size:Send buffer size of the multicast datagram socket. Default is 100'000 bytes
        mcast_recv_buf_size:Receive buffer size of the multicast datagram socket. Default is 500'000 bytes
    )
    PING(
        timeout:
        num_initial_members:Minimum number of initial members to get a response from
    )
    MERGE2(
        min_interval:Minimum time in ms between runs to discover other clusters
        max_interval:Maximum time in ms between runs to discover other clusters
    )
    FD_SOCK(
        
    )
    VERIFY_SUSPECT(
        timeout:
    )
    pbcast.NAKACK(
        retransmit_timeout:
    )
    UNICAST(
    
    )
    pbcast.STABLE(
        desired_avg_gossip:
    )
    FRAG(
    
    )
    pbcast.GMS(
        join_timeout:
        print_local_addr:
    )
 -->
    <cacheManagerPeerProviderFactory
         class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
         properties="channel=ehcache^connect=UDP(mcast_addr=231.12.21.132;mcast_port=45566;bind_port=33433;ip_ttl=32;
         mcast_send_buf_size=150000;mcast_recv_buf_size=80000):
         PING(timeout=2000;num_initial_members=6):
         MERGE2(min_interval=5000;max_interval=10000):
         FD_SOCK:VERIFY_SUSPECT(timeout=1500):
         pbcast.NAKACK(retransmit_timeout=3000):
         UNICAST:
         pbcast.STABLE(desired_avg_gossip=20000):
         FRAG:
         pbcast.GMS(join_timeout=5000;print_local_addr=true)"
         propertySeparator="^"
     />


<!--    
        <defaultCache> 是名为"default" 的<cache>
        maxElementsInMemory:内存中最大元素个数。如果开启 overflowToDisk 则超出部分转移到磁盘;如未开启则会按照 memoryStoreEvictionPolicy 回收。
        eternal:是否永驻内存
        overflowToDisk:超出后转到磁盘。文件名为<cache> 的name 加后缀.data 例如:default.data
        diskPersistent:在虚拟机重启时是否进行磁盘存储
        timeToIdleSeconds:两次访问该元素的最大时间间隔,超出后失效
        timeToLiveSeconds:创建后生存时间
        maxElementsOnDisk:磁盘中最大元素个数
        diskExpiryThreadIntervalSeconds:磁盘缓存的清理线程运行间隔 
        memoryStoreEvictionPolicy:内存回收策略
-->
    <defaultCache maxElementsInMemory="1000000" 
        eternal="false"
        overflowToDisk="false" 
        diskPersistent="false" 
        timeToIdleSeconds="120" 
        timeToLiveSeconds="300" 
        maxElementsOnDisk="10000000"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
        <!-- 同步缓存 -->
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory" />
    </defaultCache>
    
    <cache name="personCache" maxElementsInMemory="1000000" 
        eternal="false"
        overflowToDisk="false" 
        diskPersistent="false" 
        timeToIdleSeconds="120" 
        timeToLiveSeconds="300" 
        maxElementsOnDisk="10000000"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory" />
    </cache>
    
</ehcache>

bean 及 服务类:

package cn.zno;

public class Person {

    private int age;
    private Car car;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person [age=" + age + ", car=" + car + "]";
    }

}

class Car {
    private String brand;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    @Override
    public String toString() {
        return "Car [brand=" + brand + "]";
    }
}

PersonService.java

package cn.zno;

public interface PersonService {
    
    public Person getPerson();

    public void cleanPersonCache();
}

PersonServiceImpl.java

package cn.zno;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class PersonServiceImpl implements PersonService {

    @Cacheable(value = "personCache", key = "123456") 
    public Person getPerson(){
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Person person = new Person();
        Car car = new Car();
        car.setBrand("benz");
        person.setAge(11);
        person.setCar(car);
        return person;
    }

    @CacheEvict(value = "personCache", key = "123456")  
    public void cleanPersonCache() {
        System.out.println("clean personCache[123456]");
    }
    
}

测试类:

package ehcache;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import cn.zno.PersonService;

@ContextConfiguration(locations = { "classpath:applicationContext-Ehcache.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class TestEhcache {

    @Autowired
    private CacheManager cacheManager;
    @Autowired
    private PersonService personService;

    @Test
    public void show() {
        // 未缓存时耗时
        long t1 = System.currentTimeMillis();
        System.out.println(personService.getPerson().toString());
        long t2 = System.currentTimeMillis();
        System.out.println("耗时:" + (t2 - t1));
        // 缓存后耗时
        long t3 = System.currentTimeMillis();
        System.out.println(personService.getPerson().toString());
        long t4 = System.currentTimeMillis();
        System.out.println("耗时:" + (t4 - t3));
        // 清除缓存后耗时
        long t5 = System.currentTimeMillis();
        personService.cleanPersonCache();
        System.out.println(personService.getPerson().toString());
        long t6 = System.currentTimeMillis();
        System.out.println("耗时:" + (t6 - t5));
        // 再次获取
        long t7 = System.currentTimeMillis();
        System.out.println(personService.getPerson().toString());
        long t8 = System.currentTimeMillis();
        System.out.println("耗时:" + (t8 - t7));
    }
    
    @Test
    public void create(){
        cacheManager.addCache("testCache");
        Cache cache = cacheManager.getCache("testCache");
        cache.put(new Element("name", "xiaoming"));
        System.out.println(cache.get("name"));
    }
}

show()运行结果:

十月 07, 2015 11:03:22 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
信息: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
十月 07, 2015 11:03:22 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
信息: Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
十月 07, 2015 11:03:22 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
信息: Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
十月 07, 2015 11:03:22 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners
信息: Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/TransactionDefinition]
十月 07, 2015 11:03:22 上午 org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
信息: Using TestExecutionListeners: [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@15a191e, org.springframework.test.context.support.DirtiesContextTestExecutionListener@270664]
十月 07, 2015 11:03:22 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext-Ehcache.xml]
十月 07, 2015 11:03:22 上午 org.springframework.context.support.GenericApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@129df79: startup date [Wed Oct 07 11:03:22 CST 2015]; root of context hierarchy
十月 07, 2015 11:03:23 上午 org.springframework.cache.ehcache.EhCacheManagerFactoryBean afterPropertiesSet
信息: Initializing EhCache CacheManager
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

-------------------------------------------------------------------
GMS: address=pc012-16440, cluster=EH_CACHE, physical address=172.16.162.238:13451
-------------------------------------------------------------------
Person [age=11, car=Car [brand=benz]]
耗时:10031
Person [age=11, car=Car [brand=benz]]
耗时:0
clean personCache[123456]
Person [age=11, car=Car [brand=benz]]
耗时:10000
Person [age=11, car=Car [brand=benz]]
耗时:0

create()运行结果:

-------------------------------------------------------------------
GMS: address=pc012-40063, cluster=EH_CACHE, physical address=172.16.162.238:13550
-------------------------------------------------------------------
[ key = name, value=xiaoming, version=1, hitCount=1, CreationTime = 1444187930777, LastAccessTime = 1444187930777 ]

小结:

@Cacheable 的value是缓存名,key是在缓存中提取被缓存内容的key

<defaultCache  的作用是模板,不能通过default取出该缓存

<cache 可以配置到ehcache.xml 配置文件中,也可以在代码中手动添加(以<defaultCache 为模板)

mcast_addr 是组播地址,详细请查看jgroups

项目地址:git@github.com:witaste/ehcache.git

原文地址:https://www.cnblogs.com/zno2/p/4858245.html