pd-tools-j2cache模块提供的功能为缓存功能,其本质是一个starter,其他模块如果需要使用缓存功能直接引入maven坐标并提供相应配置文件即可使用。
15.1 j2cache介绍
j2cache是OSChina目前正在使用的两级缓存框架。
j2cache的两级缓存结构:
- L1: 进程内缓存 caffeine/ehcache
- L2: 集中式缓存 Redis/Memcached
j2cache其实并不是在重复造轮子,而是作资源整合,即将Ehcache、Caffeine、redis、Spring Cache等进行整合。
由于大量的缓存读取会导致L2的网络成为整个系统的瓶颈,因此L1的目标是降低对L2的读取次数。该缓存框架主要用于集群环境中。单机也可使用,用于避免应用重启导致的ehcache缓存数据丢失。
j2cache从1.3.0版本开始支持JGroups和Redis Pub/Sub两种方式进行缓存事件的通知。
数据读取顺序 -> L1 -> L2 -> DB
使用j2cache需要导入的maven坐标:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <dependency> <groupId>net.oschina.j2cache</groupId> <artifactId>j2cache-spring-boot2-starter</artifactId> <version>2.8.0-release</version> </dependency> <dependency> <groupId>net.oschina.j2cache</groupId> <artifactId>j2cache-core</artifactId> <version>2.8.0-release</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency>
|
15.2 j2cache入门案例
第一步:创建maven工程j2cache_demo并配置pom.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> </parent> <groupId>cn.itcast</groupId> <artifactId>j2cache_demo</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>net.oschina.j2cache</groupId> <artifactId>j2cache-spring-boot2-starter</artifactId> <version>2.8.0-release</version> </dependency> <dependency> <groupId>net.oschina.j2cache</groupId> <artifactId>j2cache-core</artifactId> <version>2.8.0-release</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
|
第二步:创建application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| server: port: 9000
pinda: redis: ip: 127.0.0.1 port: 6379 password: database: 0
spring: cache: type: GENERIC redis: host: ${pinda.redis.ip} password: ${pinda.redis.password} port: ${pinda.redis.port} database: ${pinda.redis.database}
j2cache: open-spring-cache: true cache-clean-mode: passive allow-null-values: true redis-client: lettuce l2-cache-open: true broadcast: net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy L1: provider_class: caffeine L2: provider_class: net.oschina.j2cache.cache.support.redis.SpringRedisProvider config_section: lettuce sync_ttl_to_redis: true default_cache_null_object: false serialization: fst caffeine: properties: /caffeine.properties lettuce: mode: single namespace: storage: generic channel: j2cache scheme: redis hosts: ${pinda.redis.ip}:${pinda.redis.port} password: ${pinda.redis.password} database: ${pinda.redis.database} sentinelMasterId: maxTotal: 100 maxIdle: 10 minIdle: 10 timeout: 10000
|
第三步:创建/resources/caffeine.properties文件
1 2 3 4 5 6 7
|
default=2000, 2h rx=50, 2h
|
第四步:创建MyController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| package cn.itcast.controller;
import net.oschina.j2cache.CacheChannel; import net.oschina.j2cache.CacheObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List;
@RestController @RequestMapping("/cache") public class MyController { private String key = "myKey"; private String region="rx"; @Autowired private CacheChannel cacheChannel;
@GetMapping("/getInfos") public List<String> getInfos(){ CacheObject cacheObject = cacheChannel.get(region, key); if(cacheObject.getValue() == null){ List<String> data = new ArrayList<String>(); data.add("info1"); data.add("info2"); cacheChannel.set(region,key,data); return data; } return (List<String>) cacheObject.getValue(); }
@GetMapping("/check") public String check(){ int check = cacheChannel.check(region, key); return "level:" + check; }
@GetMapping("/exists") public String exists(){ boolean exists = cacheChannel.exists(region, key); return "exists:" + exists; }
@GetMapping("/evict") public String evict(){ cacheChannel.evict(region,key); return "evict success"; }
@GetMapping("/clear") public String clear(){ cacheChannel.clear(region); return "clear success"; } }
|
第五步:创建启动类
1 2 3 4 5 6 7 8 9 10 11
| package cn.itcast;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication public class J2CacheApp { public static void main(String[] args) { SpringApplication.run(J2CacheApp.class,args); } }
|
注意:由于我们当前第二级缓存使用的是redis,所以需要启动redis服务才能正常运行入门案例。
启动项目,访问地址:http://localhost:9000/cache/getInfos
可以发现redis中已经缓存了数据:

重启项目,由于j2cache的一级缓存(caffeine)是进程级缓存,重启后一级缓存消失。但是二级缓存(redis)的数据还存在,再次访问上面地址,通过debug断点调试可以看到程序从redis中获取了缓存数据。
pd-tools-j2cache其实就是一个starter,我们的应用直接引入其maven坐标并配置j2cache的配置文件就可以将CacheChannel对象直接注入到我们的程序中进行缓存数据操作了。
具体使用过程和入门案例一致,只需要更换j2cache的maven坐标为pd-tools-j2cache的maven坐标即可。