1.概述

在平台中很多数据需要做缓存,比如流程定义配置,表单对象配置等等,这些对象会经常被使用到,因此需要缓存模块进行缓存。

2.系统实现

我们定义了一个cache的bootstarter。

2.1 我们定义了缓存接口类

public interface ICache {

    /**
     * 设置缓存
     * @param region    缓存类型
     * @param key       缓存key
     * @param obj       缓存数据
     */
    void set(String region, String key, Object obj);

    /**
     * 设置缓存 (这个方法一般不用)
     * @param region    缓存类型
     * @param key       缓存key
     * @param obj       缓存数据
     * @param second    缓存时间
     */
    void set(String region, String key, Object obj, long second);

这里我们定义了两个缓存的实现。

类名 说明
J2CacheImpl 基于J2Cache的实现 ,这个基于分布式的缓存实现
MemoryImpl 基于内存的实现,主要用于简单部署

2.2 缓存配置

在 j2cache-dev.properties 中做配置如下

配置说明:

配置项 配置说明
redxun.cache=memory 配置基于内存的实现,这种情况在单个微服务实例下可以生效
redxun.cache=j2cache 配置基于j2cache的实现,这个在分布式的情况下使用

另外J2cache的配置的详细配置是配置在Nacos的。

我们现在使用J2cache 是这样使用的。

使用一级缓存,禁止二级缓存,如果某个服务更新缓存,会使用REDIS去通知各个节点刷新缓存。

在配置文件中配置如下:

# 启用redis作为广播
j2cache.broadcast = redis
# 配置一二级缓存,caffeine 是作为一级缓存配置的
j2cache.L1.provider_class = caffeine
j2cache.L2.provider_class = none

# 缓存类型配置,在这里缓存的生命周期是根据类型来定义的,比如默认的是配置1000个缓存,缓存生命周期为 1小时。
caffeine.region.default = 1000, 1h 
caffeine.region.process = 1000, 1h 
caffeine.region.form = 1000, 1h 
caffeine.region.bo = 1000, 1h 
caffeine.region.boList = 1000, 1h 
caffeine.region.signature = 1000, 120s

form 表示表单的缓存,这个缓存在内存中为1000个,生命周期为1小时。

# redis 的模式有三种可选
# single 为单实例,一般用于开发环境
# sentinel 为哨兵模式 用于生产
# cluster 为集群部署模式 用于生产
redis.mode =single

redis.mode = single

#redis storage mode (generic|hash)
redis.storage = generic

## redis pub/sub channel name
redis.channel = j2cache
## redis pub/sub server (using redis.hosts when empty)
redis.channel.host =

#cluster name just for sharded
redis.cluster_name = j2cache

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

## connection
# Separate multiple redis nodes with commas, such as 192.16
#
# 8.0.10:6379,192.168.0.11:6379,192.168.0.12:6379

redis.hosts = 192.168.1.10:6379
redis.timeout = 2000
redis.password =
redis.database = 0
redis.ssl = false

## redis pool properties
redis.maxTotal = 100
redis.maxIdle = 10
redis.maxWaitMillis = 5000
redis.minEvictableIdleTimeMillis = 60000
redis.minIdle = 1
redis.numTestsPerEvictionRun = 10
redis.lifo = false
redis.softMinEvictableIdleTimeMillis = 10
redis.testOnBorrow = true
redis.testOnReturn = false
redis.testWhileIdle = true
redis.timeBetweenEvictionRunsMillis = 300000
redis.blockWhenExhausted = false
redis.jmxEnabled = false

2.3 在程序中使用

pom.xml 导入依赖包

<dependency>
   <groupId>com.redxun</groupId>
   <artifactId>jpaas-cache-spring-boot-starter</artifactId>
</dependency>

使用 CacheUtil 进行操作

region:需要和 和 j2cache-dev.properties

caffeine.region.bo = 1000, 1h 的这个配置保持一致。

//region 需要和 j2cache-dev.properties 保持一致
CacheUtil.set(String region,String key,Object obj);

2.4 测试用例

比如我在用户服务中添加两个控制器:

    @GetMapping ("/addCache")
    public String addCache() {
        //CacheUtil.remove("process","name");
        CacheUtil.set("process","name","zyg");
        return "useradd";
    }

    @GetMapping("/removeCache")
    public String  removeCache() {
        //CacheUtil.remove("process","name");
        CacheUtil.remove("process","name");

        return "user remove";
    }

这里增加缓存和删除缓存

在表单中添加两个控制器

@GetMapping("getCache")
    public String getCache(){
       String name= (String) CacheUtil.get("process","name");
       return name;
    }

    @GetMapping("addCache")
    public String addCache(){
        CacheUtil.set("process","name","zhangyg");
        return "addCache";
    }

这里是获取和添加缓存。

我们使用postman 测试缓存。

2.4.1 用例1

  1. 用户添加缓存
  2. 表单获取缓存
    这个时候我们是获取缓存是发现数据是为空的。
  3. 在表单添加缓存
    这个时候执行第二步,发现缓存已经有数据了。
  4. 用户删除缓存
    这个时候执行第二步,发现缓存被清空了。

2.4.1 用例2

  1. 在表单添加缓存
    这个时候执行第二步,发现缓存已经有数据了。
  2. 表单获取缓存
    这个时候我们是获取缓存是上一步增加的缓存
  3. 用户增加缓存
  4. 表单获取缓存
    这个时候我们缓存被清理空了。

结论:
在分布式情况下,如果缓存有变更,那么会通知其他的节点将缓存进行清空。我们读取数据的时候,先读取缓存,如果读取不到则从数据获取,获取成功后则放到缓存中。

文档更新时间: 2021-07-19 18:39   作者:zyg