Guava缓存使用

使用场景

由于公司Redis负载过大,且主从集群的设置性能较低,调用次数峰值能到达每秒5W多次,命中率仅30%,于是需要在使用的服务器上面,对特定的Redis数据添加Guava作为服务器二级缓存。
guava cache一般不用于通用的二级缓存,而是作为特定某些key值的二级缓存。

引入依赖

		<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </dependency>

代码

package com.ofpay.ofrc.order.service.sla;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author yjj
 * @date 2023/3/3
 */
@Slf4j
@Component
public class CacheService {

    @Value("${cache.initialCapacity:30}")
    private int initialCapacity;

    @Value(("${cache.maxSize:10000}"))
    private int maxSize;

    @Value("${cache.expireMinutes:10000}")
    private int expireMinutes;

    private LoadingCache<String, String> cache;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * guava缓存容器初始化
     *
     * @return 缓存容器
     */
    @PostConstruct
    private void loadCache() {
        cache = CacheBuilder.newBuilder()
                .concurrencyLevel(Runtime.getRuntime().availableProcessors())
                // 设置初始容量
                .initialCapacity(initialCapacity)
                // 设置缓存池大小
                .maximumSize(maxSize)
                // 设置失效时间
                .refreshAfterWrite(expireMinutes, TimeUnit.MINUTES)
                .build(new CacheLoader<String, String>() {
                    public String load(String key) {
                        log.info("从Redis中加载数据到guava中,key为{}", key);
                        return redisTemplate.opsForValue().get(key);
                    }
                });
    }

    /**
     * 根据key获取缓存
     *
     * @param key 键
     * @return
     */
    public String get(String key) {
        if (StringUtils.isBlank(key)) {
            log.info("获取缓存的key值为空");
            return null;
        }
        try {
            log.info("从guava缓存中获取值!key:{}", key);
            return cache.get(key);
        } catch (ExecutionException e) {
            log.error("获取缓存值出错!key为{}", key);
            return null;
        }
    }

    /**
     * 设置缓存
     *
     * @Param key 键
     * @Param value 值
     */
    public void put(String key, String value) {
        if (StringUtils.isBlank(key)) {
            log.error("设置的key值不可为空!");
            return;
        }
        cache.put(key, value);
        redisTemplate.opsForValue().set(key, value);
    }
}