jetcache缓存

jetcache缓存

码农世界 2024-05-27 前端 86 次浏览 0个评论

1 介绍

 是阿里的双极缓存,jvm-->redis-->数据库

文档:jetcache/docs/CN at master · alibaba/jetcache · GitHub

2 注意事项

  1.  使用的实体类一定实现序列化接口
  2. 定时刷新注解,慎用 它会为每一个key创建一个定时器 :场景为:key少,访问量大
  3. 注解泛型一定和方法泛型保持一致,否则报错。
  4. expire:过期时间设置为-1或者不设置 过期时间68年左右。

  5. put入参key是null不会存数据,get入参为null,会报空指针。空字符串没有任务问题。使用缓存时我们要多封装一层,判断key为空时情况

  6. 版本

3 总结

 缓存类型为BOTH时:

查询流程:

单机:本地缓存默认是100条数据(初始化数据时,留后查询的数据),redis留所有数据。本地缓存查询不到时,去redis找,保存到本地缓存,同时也去除一条本地缓存数据。

集群:第一次访问服务器A时,流程同上述一样,第二次访问服务器B时,直接去redis找,保存到本地缓存。

删除api:本地和redis都会删除数据

4  实战

   4.1 pom

        
        
            org.projectlombok
            lombok
            1.18.30
        
        
            com.alicp.jetcache
            jetcache-starter-redis
            2.7.0
        
        
        
            redis.clients
            jedis
            4.3.1
        
        
        
            com.alibaba
            fastjson
            1.2.83
        

   4.2 启动类:

@EnableMethodCache(basePackages="com.example.jetcache.mapper")
//如果不用@CreateCache注解可以删除 EnableCreateCacheAnnotation
@EnableCreateCacheAnnotation

 4.3 配置文件

jetcache:
  ## 统计间隔,默认值0,0表示不统计,开启后定期在控制台输出缓存信息
  statIntervalMinutes: 15
  ## 默认值false, 是否将 areaName 作为远程缓存key前缀
  areaInCacheName: false
  ## 本地缓存配置
  local:
    default: ## default表示全部生效,也可以指定某个cacheName
      ## 本地缓存类型,其他可选:caffeine/linkedhashmap
      type: caffeine
      # 指定KEY的转换方式, 可选 fastjson2,fastjson,jackson
      keyConvertor: fastjson
  ## 远程缓存配置
  remote:
    default: ## default表示全部生效,也可以指定某个cacheName
      type: redis
      ## key转换器方式n
      keyConvertor: fastjson
      broadcastChannel: projectA
      ## redis序列化方式
      valueEncoder: java
      valueDecoder: java
      ## redis线程池
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      ## redis地址与端口
      host: 127.0.0.1
      port: 6379

4.4 基础查询/删除/更新/定时刷新(慎用)

import com.alicp.jetcache.anno.*;
import com.example.jetcache.entity.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Mapper
public interface UserMapper {
    List queryUserAll();
    List queryUser(User user);
    /**
     * BOTH类型查询
     * expire 过期时间,redis和本地缓存一致
     * 重启服务,本地jvm消失,会先查询redis,然后存入本地缓存
     * 本地缓存存在,不会查询redis
     *
     *
     * @param id
     * @return
     */
    @Cached(name="userCache:", key="#id", expire = 15 ,cacheType = CacheType.BOTH)
    /**
     * 只要是查询过的数据,就会定时刷新,从未查询过,则无定时刷新
     * refresh: 定时器执行查询间隔时间-每过36秒就会执行一次定时器
     * stopRefreshAfterLastAccess: 表示多久不使用对应的key缓存则会停止刷新。,如果不指定会一直刷新
refreshLockTimeout:类型为BOTH/REMOTE的缓存刷新时,同时只会有一台服务器在刷新,这台服务器会在远程缓存放置一个分布式锁,此配置指定该锁的超时时间
       */
    @CacheRefresh(refresh = 36, stopRefreshAfterLastAccess = 3600, timeUnit = TimeUnit.SECONDS)
    /**
     * 注解作用——当缓存访问【未命中】的情况下,对并发进行的加载行为进行保护;当前版本实现的是单JVM内的保护,即同一个JVM中同一个key只有一个线程去加载,其它线程等待结果
     */
    @CachePenetrationProtect
    List queryUserById(String id);
    /**
     * 删除
     * @param id
     * @return
     */
    @CacheInvalidate(name="userCache.", key="#id")
    int delById(int id);
    @CacheUpdate(name="userCache.", key="#user.id", value="#user")
    int save(User user);
}

 4.5 CreateCache

          //无则新增,有则覆盖

         userCache.put(id,users);

         //删除

         userCache.remove(id);

       //删除所有数据暂无api

      

 方式一:废弃了

    @CreateCache(name= "userCache:", expire = 3600,cacheType = CacheType.BOTH)
    private Cache> userCache;
    @PostMapping(value = "/queryUserById")
    public List queryUserById(@RequestParam String id)  {
        if(CollectionUtil.isNotEmpty(userCache.get(id) )){
            return  userCache.get(id);
        }
        List users = userMapper.queryUserById(id);
       //无则新增,有则覆盖
        userCache.put(id,users);
        return users;
    }

方式二:spring注入直接使用,如上图使用API

   @Autowired

    private Cache userCache;

@Configuration
public class JetCacheConfig {
    @Autowired
    private CacheManager cacheManager;
    private Cache> userCache;
    @Resource(name = "userMapper")
    private UserMapper userMapper;
    @PostConstruct
    public void init(){
        QuickConfig qc = QuickConfig.newBuilder("userCache:")
            .expire(Duration.ofSeconds(3600))
            .cacheType(CacheType.BOTH)
            //true 集群模式下,任何本地缓存都会强制删除缓存,fasle,则请求到哪个服务,哪个服务删除本地缓存,其他服务本地缓存保持不变
            // 本地缓存更新后,将在所有的节点中删除缓存,以保持强一致性
            // 两级缓存的情况下,缓存更新时发消息让其它JVM实例中的缓存失效,需要配置broadcastChannel才生效
            .syncLocal(true)
            // 默认100 后面数据会挤掉前面的数据  本地缓存元素个数限制,只对CacheType.LOCAL和CacheType.BOTH有效
            .localLimit(100)
           //不存在时则执行这个方法
            .loader(this::loadOrderSumFromDatabase)
            //newPolicy: 定时器执行查询间隔时间
            // stopRefreshAfterLastAccess:表示多久不使用对应的key缓存则会停止刷新。
          //  .refreshPolicy(RefreshPolicy.newPolicy(6, TimeUnit.SECONDS).stopRefreshAfterLastAccess(10, TimeUnit.SECONDS))
             //cache穿透保护注释表示缓存将在多线程环境中同步加载。
            .penetrationProtect(true)
            .build();
        userCache = cacheManager.getOrCreateCache(qc);
        //查询数据库,初始化全部数据
       // userCache.putAll();
    }
    private List loadOrderSumFromDatabase(String id) {
        return userMapper.queryUserById(id);
    }
    @Bean
    public Cache> getUserCache(){
        return userCache;
    }
}

转载请注明来自码农世界,本文标题:《jetcache缓存》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,86人围观)参与讨论

还没有评论,来说两句吧...

Top