SpringBoot中集成阿里开源缓存访问框架JetCache实现声明式实例和方法缓存

场景

SpringBoot中通过自定义缓存注解(AOP切面拦截)实现数据库数据缓存到Redis:

SpringBoot中通过自定义缓存注解(AOP切面拦截)实现数据库数据缓存到Redis_霸道流氓气质的博客-CSDN博客

上面讲的通过自定义注解的方式实现查询数据库数据缓存,除此之外还有更好的轮子。

JetCache

JetCache是由阿里巴巴开源的通用缓存访问框架,如果你对Spring Cache很熟悉的话,请一定花一点时间了解一下JetCache,

它更好用。JetCache提供的核心能力包括:

提供统一的,类似jsr-107风格的API访问Cache,并可通过注解创建并配置Cache实例

通过注解实现声明式的方法缓存,支持TTL和两级缓存

分布式缓存自动刷新,分布式锁 (2.2+)

支持异步Cache API

Spring Boot支持

Key的生成策略和Value的序列化策略是可以定制的

扫描二维码关注公众号,回复: 15785533 查看本文章

针对所有Cache实例和方法缓存的自动统计

官方仓库地址:

https://github.com/alibaba/jetcache

中文文档地址:

https://github.com/alibaba/jetcache/blob/master/docs/CN/GettingStarted.md

注:

博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主

实现

1、首先搭建SpringBoot项目并引入相关web、mysql、mybatis等相关依赖,然后添加JetCache依赖

        <dependency>
            <groupId>com.alicp.jetcache</groupId>
            <artifactId>jetcache-starter-redis</artifactId>
            <version>2.6.0</version>
        </dependency>

注意这里的版本为2.6.0,要注意从2.7.0开始有些改动,具体可查看官方文档说明。

这里附其他所需的依赖,其他依赖以及版本具体根据自己需要决定。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <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>
        <!--MySQL驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--MyBatis整合SpringBoot框架的起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>com.alicp.jetcache</groupId>
            <artifactId>jetcache-starter-redis</artifactId>
            <version>2.6.0</version>
        </dependency>
    </dependencies>

2、找到yml配置文件,添加如下配置

jetcache:
  #统计间隔,0表示不统计
  statIntervalMinutes: 15
  areaInCacheName: false
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      keyConvertor: fastjson
      valueEncoder: java
      valueDecoder: java
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: 127.0.0.1
      port: 6379
      password: 123!

注意这里的最后面添加了jedis连接redis时的密码,这里本地的redis是需要密码验证的。

其他具体配置参考官方文档:

https://github.com/alibaba/jetcache/blob/master/docs/CN/Config.md

配置通用说明如下

属性 默认值 说明
jetcache.statIntervalMinutes 0 统计间隔,0表示不统计
jetcache.areaInCacheName true(2.6-) false(2.7+) jetcache-anno把cacheName作为远程缓存key前缀,2.4.3以前的版本总是把areaName加在cacheName中,因此areaName也出现在key前缀中。2.4.4以后可以配置,为了保持远程key兼容默认值为true,但是新项目的话false更合理些,2.7默认值已改为false。
jetcache.hiddenPackages @Cached和@CreateCache自动生成name的时候,为了不让name太长,hiddenPackages指定的包名前缀被截掉
jetcache.[local/remote].${area}.type 缓存类型。tair、redis为当前支持的远程缓存;linkedhashmap、caffeine为当前支持的本地缓存类型
jetcache.[local/remote].${area}.keyConvertor fastjson2 key转换器的全局配置,2.6.5+已经支持的keyConvertor:fastjson2/jackson
2.6.5-只有一个已经实现的keyConvertor:fastjson。仅当使用@CreateCache且缓存类型为LOCAL时可以指定为none,此时通过equals方法来识别key。方法缓存必须指定keyConvertor
jetcache.[local/remote].${area}.valueEncoder java 序列化器的全局配置。仅remote类型的缓存需要指定,2.7+可选java/kryo/kryo5;2.6-可选java/kryo
jetcache.[local/remote].${area}.valueDecoder java 序列化器的全局配置。仅remote类型的缓存需要指定,2.7+可选java/kryo/kryo5;2.6-可选java/kryo
jetcache.[local/remote].${area}.limit 100 每个缓存实例的最大元素的全局配置,仅local类型的缓存需要指定。注意是每个缓存实例的限制,而不是全部,比如这里指定100,然后用@CreateCache创建了两个缓存实例(并且注解上没有设置localLimit属性),那么每个缓存实例的限制都是100
jetcache.[local/remote].${area}.expireAfterWriteInMillis 无穷大 以毫秒为单位指定超时时间的全局配置(以前为defaultExpireInMillis)
jetcache.remote.${area}.broadcastChannel jetcahe2.7的两级缓存支持更新以后失效其他JVM中的local cache,但多个服务共用redis同一个channel可能会造成广播风暴,需要在这里指定channel,你可以决定多个不同的服务是否共用同一个channel。如果没有指定则不开启。
jetcache.local.${area}.expireAfterAccessInMillis 0 需要jetcache2.2以上,以毫秒为单位,指定多长时间没有访问,就让缓存失效,当前只有本地缓存支持。0表示不使用这个功能。

3、找到启动类添加如下两个注解来开启注解支持

@SpringBootApplication
@EnableMethodCache(basePackages = "com.badao.demo")

添加位置

4、使用注解@CreateCache创建缓存实例

首先声明一个User,这里使用了lombok注解

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {

    private static final long serialVersionUID = -5514139686858156155L;

    private Integer id;

    private Integer userId;

    private String name;

    private Integer age;

}

然后在serviceImpl中声明实例

    @CreateCache(expire = 100)
    private Cache<Long, User> userCache;

然后再service具体方法中使用,使用方式与map一样

    @Override
    public void cacheHandler() {
        //创建缓存并使用,使用方式和map一样
        User user = new User();
        user.setName("badao");
        userCache.put(1l,user);
        User user1 = userCache.get(1l);
        System.out.println(user1);
        //userCache.remove(1l);
    }

注意这里的注解只声明了过期时间,其他都是使用默认属性,这里表示100秒过期。

默认存储类型为远端即redis存储。

cacheType有LOCAL/REMOTE/BOTH三种选择,分别代表本地内存/远程Cache Server(例如Redis)/两级缓存,

可根据情况选用,合理的使用LOCAL或BOTH类型可以降低Cache Server的压力以及我们提供的服务的响应时间。

我们在controller中调用该service并进行测试

发现其缓存成功,因为没指定key所以是默认名字。

比如我们修改上面的注解的内容为

@CreateCache(name = "userCache",expire = 100,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.LOCAL)

这里就设置了将其缓存在内存并指定了名字。

还可以如此设置

@CreateCache(name = "userCache",expire = 100,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.BOTH,localLimit = 50)

更多详细配置参考官方文档:

https://github.com/alibaba/jetcache/blob/master/docs/CN/CreateCache.md

@CreateCache属性表

属性 默认值 说明
area “default” 如果需要连接多个缓存系统,可在配置多个cache area,这个属性指定要使用的那个area的name
name 未定义 指定缓存的名称,不是必须的,如果没有指定,会使用类名+方法名。name会被用于远程缓存的key前缀。另外在统计中,一个简短有意义的名字会提高可读性。如果两个@CreateCachenamearea相同,它们会指向同一个Cache实例
expire 未定义 该Cache实例的默认超时时间定义,注解上没有定义的时候会使用全局配置,如果此时全局配置也没有定义,则取无穷大
timeUnit TimeUnit.SECONDS 指定expire的单位
cacheType CacheType.REMOTE 缓存的类型,包括CacheType.REMOTE、CacheType.LOCAL、CacheType.BOTH。如果定义为BOTH,会使用LOCAL和REMOTE组合成两级缓存
localLimit 未定义 如果cacheType为CacheType.LOCAL或CacheType.BOTH,这个参数指定本地缓存的最大元素数量,以控制内存占用。注解上没有定义的时候会使用全局配置,如果此时全局配置也没有定义,则取100
serialPolicy 未定义 如果cacheType为CacheType.REMOTE或CacheType.BOTH,指定远程缓存的序列化方式。JetCache内置的可选值为SerialPolicy.JAVA和SerialPolicy.KRYO。注解上没有定义的时候会使用全局配置,如果此时全局配置也没有定义,则取SerialPolicy.JAVA
keyConvertor 未定义 指定KEY的转换方式,用于将复杂的KEY类型转换为缓存实现可以接受的类型,JetCache内置的可选值为KeyConvertor.FASTJSON和KeyConvertor.NONE。NONE表示不转换,FASTJSON通过fastjson将复杂对象KEY转换成String。如果注解上没有定义,则使用全局配置。

5、使用注解@Cached创建方法缓存

使用@Cached方法可以为一个方法添加上缓存。JetCache通过Spring AOP生成代理,来支持缓存功能。

注解可以加在接口方法上也可以加在类方法上,但需要保证是个Spring bean。

比如我们service中将一个查询mysql数据库的方法添加注解并指定名字和过期时间

    @Cached(name = "methodCacheHandler",expire = 3600)
    List<User> methodCacheHandler();

方法具体实现

    @Override
    public List<User> methodCacheHandler() {
        return userMapper.findAll();
    }

调用该方法会发现只有第一次查询了数据库

6、使用注解@CacheRefresh实现自动刷新

如果需要定期从数据库中查询并更新一次缓存数据可以这样用

    @Cached(name = "methodCacheHandler",expire = 3600)
    @CacheRefresh(timeUnit = TimeUnit.SECONDS,refresh = 10)
    List<User> methodCacheHandler();

比如这里设置10秒自动刷新一次,测试效果

 

更多功能和说明参考官方文档。

7、遇到的那些坑

如果提示:

The dependencies of some of the beans in the application context from a cycle:

redisAutoInit->springConfigProvider

 

在yml中spring节点下配置允许循环依赖

  #解决jetcache循环依赖问题
  main:
    allow-circular-references: true

如果提示:

jetcache(RedisCache) PUT error,...Could not get a resource from the pool

 

则检查配置的redis是否启动以及连接信息是否正确。

如果提示:

JedisDataException:NoAuth Authentication required

则在配置文件中加入redis的连接密码

猜你喜欢

转载自blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131662049