首先看下整合过程
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: 8778spring:application:name: websitecache:ehcache:config: classpath:/ehcache.xmlj2cache:config-location: classpath:/j2cache.propertiescache-clean-mode: activeopen-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\\"/><defaultCachemaxElementsInMemory="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 {@AutowiredJ2cacheService 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 {@AutowiredCacheChannel cacheChannel;@Overridepublic String addCache(String key,String value) {cacheChannel.set("Euser",key,value);return "region:Euser,key:"+key+",value:"+value;}@Overridepublic 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();}@Overridepublic String getKey(String key) {Object v = cacheChannel.get("Euser",key);if(v != null){return v.toString();}return "null";}@Overridepublic 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;}}
}

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

  1. SpringBoot 集成 layering-cache 实现两级缓存调研与实践

    前言 对于系统查多改少的数据,可以通过缓存来提升系统的访问性能.一般情况下我们会采用 Redis ,但是如果仅仅依赖 Redis 很容易出现缓存雪崩的情况.为了防止缓存雪崩可以通过 Redis 高可用 ...

  2. Springboot+caffeine 实现两级缓存

    目录: 缓存.两级缓存 spring cache:主要包含spring cache定义的接口方法说明和注解中的属性说明 spring boot + spring cache caffeine简介 sp ...

  3. SpringBoot整合(四)整合Ehcache、Redis、Memcached、jetcache、j2cache缓存

    ​ 企业级应用主要作用是信息处理,当需要读取数据时,由于受限于数据库的访问效率,导致整体系统性能偏低. ​ 为了改善上述现象,开发者通常会在应用程序与数据库之间建立一种临时的数据存储机制,该区域中的数 ...

  4. j2cache两级缓存框架

    j2cache介绍 j2cache是OSChina目前正在使用的两级缓存框架. j2cache的两级缓存结构: L1: 进程内缓存 caffeine/ehcache L2: 集中式缓存 Redis/M ...

  5. J2cache两级缓存原理

    1.关于开源中国的一些数据 2.OSChina的几种缓存策略 3.Ehcache缓存架构 4.实际运行存在的问题 5.混村系统选型时的考量 6.J2Cache--两级缓存框架(内存,磁盘) 每天 IP ...

  6. 【Caffeine进阶】Redis+Caffeine 两级缓存实战,性能爆缸

    往期回顾 博主前面发过一篇[缓存框架Caffeine]初级篇,主要介绍了Caffeine的入门级使用!地址https://blog.csdn.net/Number_oneEngineer/articl ...

  7. Redis+Caffeine两级缓存

    1.前言 在高性能的服务架构设计中,缓存是一个不可或缺的环节.在实际的项目中,我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中,只有当缓存的访问没有命中时再查询数据库.在提升 ...

  8. 高性能两级缓存J2Cache

    今天给大家推荐一个开源项目,J2Cache,一个很完善的两级缓存项目,作者是-红薯(开源中国CTO) 介绍 开源项目地址:https://gitee.com/ld/J2Cache/tree/maste ...

  9. java l1 l2缓存,Java 两级缓存框架

    概述介绍 J2Cache 是 OSChina 目前正在使用的两级缓存框架(要求至少 Java 8).第一级缓存使用内存(同时支持 Ehcache 2.x.Ehcache 3.x 和 Caffeine) ...

  10. J2Cache 两级缓存中的 Region 到底是什么东西?

    2019独角兽企业重金招聘Python工程师标准>>> 不时有人来询问 J2Cache 里的 Region 到底是什么概念,这里做统一的解答. J2Cache 的 Region 来源 ...

最新文章

  1. cocos2d 0.99.5版本屏幕默认是横屏,怎么修改为竖屏呢?
  2. Cisco Catalyst交换机密码恢复策略
  3. tcp三次握手和syn 洪水攻击
  4. CI/CD大幅减少甩锅!
  5. Windows上基于快捷方式的Putty免密码登陆
  6. c++builder 6 转成vs_官方:欧洲杯将在2021年6月11日至7月11日进行,举办城市不变...
  7. java中用单例模式有什么好处
  8. jBPM与业务系统集成-通过定制Task Instance等方式实现
  9. Mac 技巧——让Mac轻松访问Windows网络共享
  10. [Linked List]Intersection of Two Linked Lists
  11. php检测手机是否开飞行模式,Android_android 如何判断当前是否为飞行模式,Android中如何判断系统当前是否 - phpStudy...
  12. 学习笔记——Servlet原理
  13. ftp服务器端口修改,FTP端口:默认为21端口
  14. 移动网络安装测试软件,家宽众测中国移动手机版(在线宽带网速测试器)V2.0.3 去广告版...
  15. MQ--推模式与拉模式
  16. 华为云产品介绍—大数据
  17. 用网络求t图的几篇论文框架图
  18. ASCII字符集详解
  19. vs2015c语言内嵌汇编,C#中内嵌资源的读取
  20. Python高级-前端-03-Javascript

热门文章

  1. 知识总结2:Django常见面试题总结(持续更新)
  2. Lua EmmyLua 注解详解
  3. 618号外:MS08067安全实验室也做安全培训了
  4. 中小型城市商业银行数字化转型实践(一)整体技术架构转型(双态IT)
  5. java供应商管理系统项目简介,基于jsp的供应商管理系统-JavaEE实现供应商管理系统 - java项目源码...
  6. 关于RS485的使用
  7. 基站定位php,基于Python的移动联通基站接口调用代码实例
  8. 基础晶体管放大电路设计七步走
  9. 从设计心理学理解交互设计的原则
  10. 华为各系列交换机限速配置