J2Cache 缓存框架讲解;SpringBoot 整合 J2Cache 代码示例
- J2Cache 介绍
- J2Cache 本身并不是一种缓存,其是一个缓存整合框架,可以提供缓存的整合方案,是各种缓存搭配使用,自身并不提供缓存功能。
- JetCache 和 J2Cache 对比:
1、JetCache :为了让 JetCache 支持的缓存框架(JetCache共支持四种缓存,本地缓存两种:LinkedHashMap、Caffeine;远程缓存两种:Redis、Tair)通过 JetCache 实现统一的接口调用,让你不需要关心底层缓存的 API 细节,这是设计模式层面上的封装。
2、J2Cache 是一种全新的缓存功能设计。它是一个两级的缓存框架,其支持所有的缓存。它主要要解决的问题是:
(1)使用内存缓存时,一旦应用重启后,由于缓存数据丢失,缓存雪崩,给数据库造成巨大压力,导致应用堵塞。
(2)使用内存缓存时,多个应用节点无法共享缓存数据。
(3)使用集中式缓存,由于大量的数据通过缓存获取,导致缓存服务的数据吞吐量太大,带宽跑满。现象就是 Redis 服务负载不高,但是由于机器网卡带宽跑满,导致数据读取非常慢。
- 引入 J2Cache 依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--springboot j2cache-->
<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>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
- 配置yml:
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
username: user
password: 123456
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# j2cache相关配置,指定j2cache的
j2cache:
config-location: j2cache.properties
- j2cache.properties配置文件:
# j2cache.properties 的完整配置在 j2cache-core 的 jar 包中有,可参照配置
# 一级缓存
j2cache.L1.provider_class = ehcache
ehcache.configXml = ehcache.xml
# 设置是否启用二级缓存
j2cache.l2-cache-open = true
# 二级缓存
j2cache.L2.provider_class = net.oschina.j2cache.cache.support.redis.SpringRedisProvider
j2cache.L2.config_section = redis
redis.hosts = localhost:6379
redis.password = hd123
# redis缓存的key的命名空间,默认为空
redis.namespace =
# 一级缓存中的数据如何到达二级缓存
j2cache.broadcast = net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy
- ehcache.xml 配置:
<!-- for ehcache 2.x -->
<ehcache updateCheck="false" dynamicConfig="false">
<diskStore path="java.io.tmpdir"/>
<cacheManagerEventListenerFactory class="" properties=""/>
<!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.
The following attributes are required for defaultCache:
maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.
-->
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="true">
</defaultCache>
<!--Predefined caches. Add your cache configuration settings here.
If you do not have a configuration for your cache a WARNING will be issued when the
CacheManager starts
The following attributes are required for defaultCache:
name - Sets the name of the cache. This is used to identify the cache. It must be unique.
maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.
-->
<cache name="example"
maxElementsInMemory="5000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
>
</cache>
</ehcache>
- 实体类Book.java
import lombok.*;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book implements Serializable {
private String id;
private String name;
private String description;
private Float price;
}
- 业务层代码示例:
// BookService.java
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.springboot.entity.Book;
public interface BookService extends IService<Book> {
Book getCacheById(String id);
String checkCacheById(String id);
}
// BookServiceImpl.java
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.dao.BookDao;
import com.example.springboot.entity.Book;
import com.example.springboot.service.BookService;
import net.oschina.j2cache.CacheChannel;
import net.oschina.j2cache.CacheObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements BookService {
@Autowired
private CacheChannel cacheChannel;
@Override
public Book getCacheById(String id) {
cacheChannel.set("j2Cache_", id, getById(id));
return null;
}
@Override
public String checkCacheById(String id) {
String aDefault = cacheChannel.get("j2Cache_", id).asString();
return aDefault;
}
}
- 表现层代码如下:
import com.example.springboot.entity.Book;
import com.example.springboot.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("{id}")
public Book getById(@PathVariable String id){
return bookService.getCacheById(id);
}
@PostMapping
public String checkById(@RequestBody Book book){
return bookService.checkCacheById(book.getId());
}
}
- Postman 测试如下:
-
往缓存中放数据:
-
从缓存中取数据: