Guava Cache、LoadingCache本地缓存的使用

前言:由于用户系统重构存在新老版本,网关对部分数据进行路径写死,所以为了避免频繁请求接口对网关日志记录进行本地缓存处理,学习过程中有Cache和LoadingCache两种模式,一番测试下都可以正常使用,特此记录

准备工作

  • 添加依赖
<!-- guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.1-jre</version>
</dependency>

Cache的使用

Guava Cache、LoadingCache本地缓存的使用_第1张图片

构造之后直接使用cache.get以及cache.put把它当成一个map来使用就行,也可以自己封装一个工具类来使用,这里不做过多赘述。

LoadingCache 的使用

  • 使用前先介绍下三种过期规则

expireAfterAccess: 当缓存项在指定的时间段内没有被读或写就会被回收。

expireAfterWrite:当缓存项在指定的时间段内没有更新就会被回收(移除key),需要等待获取新值才会返回。

refreshAfterWrite:当缓存项上一次更新操作之后的多久会被刷新。第一个请求进来,执行load把数据加载到内存中(同步过程),指定的过期时间内比如10秒,都是从cache里读取数据。过了10秒后,没有请求进来,不会移除key。再有请求过来,才则执行reload,在后台异步刷新的过程中,如果当前是刷新状态,访问到的是旧值。刷新过程中只有一个线程在执行刷新操作,不会出现多个线程同时刷新同一个key的缓存。在吞吐量很低的情况下,如很长一段时间内没有请求,再次请求有可能会得到一个旧值(这个旧值可能来自于很长时间之前),这将会引发问题。(可以使用expireAfterWrite和refreshAfterWrite搭配使用解决这个问题)

  • 由于我的需求是5分钟加载(load方法)一次,所以我仅仅使用了expireAfterWrite
    private LoadingCache<String, String> cache = CacheBuilder.newBuilder()
            .expireAfterWrite(5, TimeUnit.MINUTES)      // 设置访问后5min的过期时间
            .initialCapacity(100)
            .maximumSize(4000)
            .build(new CacheLoader<String, String>() {
                @Override   // 加载缓存的方法, 必须实现
                public String load(String key) throws Exception{
                    return selector();
                }
            });

    /**
     * 版本选择器-老版tu和新版ks用户体系选择
     * @return
     */
    private String selector(){
        // 为空或者异常或者"value":"0" 都为false
        boolean succ = false;
        try {
            succ = ksService.versionSelector();
        } catch (Exception e) {

        }
        return succ ? "/ks-prj" : "/tu-prj";
    }

    public String getAppend(){
        try {
            // 获取本地缓存设置的值,当前缓存定制化,随意传参
            return cache.get("1");
        } catch (ExecutionException e) {
            log.error("本地缓存异常:{}",e);
        }
        return selector();
    }
测试
 // 随机设置selector的值,验证缓存是否生效和过期时间是否重新加载
 public String selector() {
        Random random = new Random();
        return String.valueOf(random.nextInt());
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CacheBuildUtils utils = new CacheBuildUtils();
        while (true){
            String s = utils.dataLoadingCache.get("111");
            System.out.println(s);
            Thread.sleep(5000);
        }
    }

你可能感兴趣的:(工作日常,缓存,java)