Springboot使用J2Cache,整合ehcache和redis缓存框架,实现两级缓存

9 篇文章 0 订阅
2 篇文章 0 订阅
首先看下整合过程
1、pom.xml添加相关依赖
<!-- 添加ehcache支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Ehcache 坐标 -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.4</version>
</dependency>
<!--整合redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.1.6.RELEASE</version>
</dependency>
<!--整合j2cache-->
<dependency>
    <groupId>net.oschina.j2cache</groupId>
    <artifactId>j2cache-spring-boot2-starter</artifactId>
    <version>2.7.6-release</version>
</dependency>
<dependency>
    <groupId>net.oschina.j2cache</groupId>
    <artifactId>j2cache-core</artifactId>
    <version>2.7.7-release</version>
</dependency>

2、application.yml添加配置

server:
  port: 8778

spring:
  application:
    name: website
  cache:
    ehcache:
      config: classpath:/ehcache.xml

j2cache:
  config-location: classpath:/j2cache.properties
  cache-clean-mode: active
  open-spring-cache: true

3、resources添加ehcache.xml和j2cache.properties配置文件

ehcache.xml内容

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <!--设置磁盘存储路径-->
    <diskStore path="D:\\ehcache\\"/>
    <defaultCache
            maxElementsInMemory="1000"
            eternal="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            overflowToDisk="true">
    </defaultCache>
    <cache name="Euser"
           eternal="false"
           maxEntriesLocalHeap="2000"
           timeToIdleSeconds="2000"
           timeToLiveSeconds="2000"
           maxElementsInMemory="10000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU"
           overflowToDisk="true" >
    </cache>
</ehcache>

j2cache.properties内容

#J2Cache configuration
#j2cache 源码地址https://gitee.com/ld/J2Cache

#########################################
# Cache Broadcast Method
# values:
# jgroups -> use jgroups's multicast
# redis -> use redis publish/subscribe mechanism
#########################################
#广播策略
#j2cache.broadcast = net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy
j2cache.broadcast = redis

# 是否开启二级缓存
j2cache.l2-cache-open=true
j2cache.open-spring-cache= true
j2cache.allow-null-values= true
j2cache.cache-clean-mode= active
j2cache.redis-client=jedis

#组播的通道名称
jgroups.channel.name = j2cache

#########################################
# Level 1&2 provider
# values:
# none -> disable this level cache
# ehcache -> use ehcache2 as level 1 cache
# ehcache3 -> use ehcache3 as level 1 cache
# caffeine -> use caffeine as level 1 cache(only in memory)
# redis -> use redis(hashs) as level 2 cache
# [classname] -> use custom provider
#########################################
#一级缓存使用ehcache3
j2cache.L1.provider_class = ehcache
#j2cache.L2.provider_class = net.oschina.j2cache.cache.support.redis.SpringRedisProvider
j2cache.L2.provider_class = redis
#二级缓存使用redis
#j2cache.L2.provider_class = redis
j2cache.L2.config_section = redis

#########################################
# Cache Serialization Provider
# values:
# fst -> fast-serialization
# kyro -> kyro
# java -> java standard
# [classname implements Serializer]
#########################################

j2cache.serialization = fst

#########################################
# Ehcache configuration
#########################################

#ehcache.name=
ehcache.configXml=/ehcache.xml
#ehcache3.configXml = /ehcache.xml

#########################################
# Caffeine configuration
# caffeine.region.[name] = size, xxxx[s|m|h|d]
#
#########################################

caffeine.region.default = 1000, 1h 

#########################################
# Redis connection configuration
#########################################

#########################################
# Redis Cluster Mode
#
# single -> single redis server
# sentinel -> master-slaves servers
# cluster -> cluster servers (数据库配置无效,使用 database = 0)
# sharded -> sharded servers  (密码、数据库必须在 hosts 中指定,且连接池配置无效 ; redis://user:password@127.0.0.1:6379/0)
#
#########################################

#redis.mode = sentinel
redis.mode = single
#cluster name just for sharded
redis.cluster_name = mymaster

## redis cache namespace optional, default[j2cache]
redis.namespace = j2cache

## connection
#redis.hosts = 127.0.0.1:26378,127.0.0.1:26379,127.0.0.1:26380
redis.hosts = 127.0.0.1:6379
redis.timeout = 2000
redis.password = 123456
redis.database = 0

## redis pub/sub channel name
redis.channel = j2cache

## redis pool properties
redis.maxTotal = -1
redis.maxIdle = 2000
redis.maxWaitMillis = 100
redis.minEvictableIdleTimeMillis = 864000000
redis.minIdle = 1000
redis.numTestsPerEvictionRun = 10
redis.lifo = false
redis.softMinEvictableIdleTimeMillis = 10
redis.testOnBorrow = true
redis.testOnReturn = false
redis.testWhileIdle = false
redis.timeBetweenEvictionRunsMillis = 300000
redis.blockWhenExhausted = true

4、增删改查demo测试

package com.example.website.controller;

import com.example.website.service.J2cacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 
 * @date 2019/6/27 0027
 */
@RestController
@RequestMapping("/index")
public class IndexController {

    @Autowired
    J2cacheService j2cacheService;

    @RequestMapping("/j2cache")
    public String j2cache(@RequestParam("key")String key,@RequestParam("value")String value){
        return j2cacheService.addCache(key,value);
    }

    @RequestMapping("/queryCache")
    public String queryRedis(@RequestParam("type")String type){
        return j2cacheService.queryCache(type);
    }

    @RequestMapping("/getKey")
    public String getKey(@RequestParam("key")String key){
        return j2cacheService.getKey(key);
    }

    @RequestMapping("/deleteKey")
    public String deleteKey(@RequestParam("key")String key){
        return j2cacheService.deleteKey(key);
    }
}
package com.example.website.service;

/**
 * @author 
 * @date 2019/6/28 0028
 */
public interface J2cacheService {

    public String addCache(String key,String value);

    public String queryCache(String type);

    public String getKey(String key);

    public String deleteKey(String key);
}
package com.example.website.service.impl;

import com.example.website.service.J2cacheService;
import net.oschina.j2cache.CacheChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;

/**
 * @author 
 * @date 2019/6/28 0028
 */
@Service
public class J2cacheServiceImpl implements J2cacheService {

    @Autowired
    CacheChannel cacheChannel;

    @Override
    public String addCache(String key,String value) {
        cacheChannel.set("Euser",key,value);
        return "region:Euser,key:"+key+",value:"+value;
    }

    @Override
    public String queryCache(String type) {

        StringBuilder sb = new StringBuilder();
        if("1".equals(type)){
            System.out.println("ehcache缓存==================");
            //CacheProvider l1 = cacheChannel.getL1Provider();
            Collection<String> keys = cacheChannel.keys("Euser");
            for(String key : keys){
                sb.append("key:"+key+",value:"+cacheChannel.get("Euser",key));
            }
        }else if("2".equals(type)){
            System.out.println("redis二级缓存================");
            //CacheProvider l2 = cacheChannel.getL2Provider();
            Collection<String> keys = cacheChannel.keys("Euser");
            for(String key : keys){
                sb.append("key:"+key+",value:"+cacheChannel.get("Euser",key));
            }
        }
        return sb.toString();
    }

    @Override
    public String getKey(String key) {
        Object v = cacheChannel.get("Euser",key);
        if(v != null){
            return v.toString();
        }
        return "null";
    }

    @Override
    public String deleteKey(String key) {
        cacheChannel.evict("Euser",key);
        return "success";
    }
}

redis数据

本地D盘会根据设置的目录,存储ehcache数据

增加

删除

key:4 已被删除

修改

修改跟增加是一样的,它会覆盖原有的key值对应的value 

查询

cacheChannel.set("Euser",key,value);

J2Cache set key和value,会直接存入L1和L2。当我们重启服务器的时候,L1 ehcache被清空,L2 redis数据存在,这个时候,我们去遍历数据,跟踪源码,我们会发现请求去L1取不到数据,这个时候就会去L2取数据,取到数据就会再次放入L1,下次查询就不需要去L2查询了,直接从L1获取数据。

CacheObject obj = new CacheObject(region, key, (byte)1);
obj.setValue(this.holder.getLevel1Cache(region).get(key));//先从L1查询
if (obj.rawValue() != null) {
    return obj;//L1查询到对象就返回
} else {
    String lock_key = key + '%' + region;
    synchronized(_g_keyLocks.computeIfAbsent(lock_key, (v) -> {
        return new Object();
    })) {
        obj.setValue(this.holder.getLevel1Cache(region).get(key));//从L1查询
        if (obj.rawValue() != null) {
            return obj;
        } else {
            try {//L1查询不到数据,从L2查询
                obj.setLevel((byte)2);
                obj.setValue(this.holder.getLevel2Cache(region).get(key));
                if (obj.rawValue() != null) {
                    this.holder.getLevel1Cache(region).put(key, obj.rawValue());//并且从L1查询到数据并放入L2
                } else {
                    boolean cacheNull = cacheNullObject.length > 0 ? cacheNullObject[0] :                                   this.defaultCacheNullObject;
                    if (cacheNull) {
                        this.set(region, key, this.newNullObject(), true);
                    }
                }
            } finally {
                _g_keyLocks.remove(lock_key);
            }

            return obj;
        }
    }
}

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Spring Boot 3整合J2Cache,可以按照以下步骤进行操作: 1. 在pom.xml文件中添加J2CacheRedisEhcache的依赖。 2. 在application.properties或application.yml文件中配置一级和二级缓存,并配置一二级缓存间数据传递方式。 3. 在代码中使用J2Cache提供的注解来实现缓存功能。 具体操作步骤如下: 1. 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>net.oschina.j2cache</groupId> <artifactId>j2cache-core</artifactId> <version>2.8.4-release</version> </dependency> <dependency> <groupId>net.oschina.j2cache</groupId> <artifactId>j2cache-spring-boot2-starter</artifactId> <version>2.8.0-release</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.6.0</version> </dependency> ``` 2. 在application.properties或application.yml文件中添加以下配置: ``` # 1级缓存 j2cache.L1.provider_class = ehcache ehcache.configXml = ehcache.xml # 2级缓存 j2cache.L2.provider_class = net.oschina.j2cache.cache.support.redis.SpringRedisProvider j2cache.L2.config_section = redis redis.hosts = localhost:6379 # 1级缓存中的数据如何到达二级缓存 j2cache.broadcast = net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy ``` 3. 在代码中使用J2Cache提供的注解来实现缓存功能,例如: ``` @CachePut(name = "myCache", key = "#id") public User updateUser(String id, User user) { // 更新用户信息 return user; } @Cacheable(name = "myCache", key = "#id") public User getUser(String id) { // 查询用户信息 return user; } @CacheEvict(name = "myCache", key = "#id") public void deleteUser(String id) { // 删除用户信息 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值