使用Caffeine实现帖子的缓存来优化网站的运行速度

导入依赖

xml 复制代码
		<!-- https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine -->
		<dependency>
			<groupId>com.github.ben-manes.caffeine</groupId>
			<artifactId>caffeine</artifactId>
			<version>3.1.7</version>
		</dependency>

在Service层中调用Caffeine的接口

java 复制代码
@Service
public class DiscussPostService {

    private final static Logger logger = LoggerFactory.getLogger(DiscussPostService.class);

    @Autowired
    private DiscussPostMapper discussPostMapper;

    @Value("${caffeine.posts.max-size}")
    private int maxSize;

    @Value("${caffeine.posts.expire-seconds}")
    private int expireSeconds;

    // Caffeine's core API: Cache, LoadingCache, AsyncLoadingCache

    // posts list cache
    private LoadingCache<String, List<DiscussPost>> postListCache;

    // posts total number cache
    private LoadingCache<Integer, Integer> postRowsCache;

    @PostConstruct
    public void init(){
        // initialize the post list cache
        postListCache = Caffeine.newBuilder()
                .maximumSize(maxSize)
                .expireAfterWrite(expireSeconds, TimeUnit.SECONDS)
                .build(new CacheLoader<String, List<DiscussPost>>() {
                    @Override
                    public @Nullable List<DiscussPost> load(String key) throws Exception {
                        if(key == null || key.length() == 0){
                            throw new IllegalArgumentException("parameter error: key must not be null");
                        }
                        String[] params = key.split(":");
                        if(params == null || params.length != 2) {
                            throw new IllegalArgumentException("parameter error");
                        }
                        int offset = Integer.valueOf(params[0]);
                        int limit = Integer.valueOf(params[1]);

                        // in there, we can add second level cache, such as Redis
                        // if we can't find data in the Redis, then query it in MySQL

                        logger.debug("load post list from DB...");
                        return discussPostMapper.selectDiscussPosts(0, offset, limit, 1);
                    }
                });
        // initialize the post total number cache
        postRowsCache = Caffeine.newBuilder()
                .maximumSize(maxSize)
                .expireAfterWrite(expireSeconds, TimeUnit.SECONDS)
                .build(new CacheLoader<Integer, Integer>() {
                    @Override
                    public @Nullable Integer load(Integer key) throws Exception {
                        logger.debug("load post list from DB...");
                        return discussPostMapper.selectDiscussPostRows(key);
                    }
                });
    }

    public List<DiscussPost> findDiscussPosts(int userId, int offset, int limit, int orderMode) {
        if(userId == 0 && orderMode == 1){
            return postListCache.get(offset + ":" + limit);
        }
        logger.debug("load post list from DB...");
        return discussPostMapper.selectDiscussPosts(userId, offset, limit, orderMode);
    }

    public int findDiscussPostRows(int userId) {
        if (userId == 0) {
            return postRowsCache.get(userId);
        }
        logger.debug("load post rows from DB...");
        return discussPostMapper.selectDiscussPostRows(userId);
    }
}

测试

java 复制代码
@SpringBootTest
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyCommunityApplication.class)
public class CaffeineTest {

    @Autowired
    private DiscussPostService postService;

    @Test
    public void testCache(){
        System.out.println(postService.findDiscussPosts(0, 0, 10, 1));
        System.out.println(postService.findDiscussPosts(0, 0, 10, 1));
        System.out.println(postService.findDiscussPosts(0, 0, 10, 1));
        System.out.println(postService.findDiscussPosts(0, 0, 10, 0));
    }
}

结果:

可以看到,第一次记录还未加入缓存,所以是从DB中加载,而后两次访问记录都是从Caffeine中加载的;最后一次访问是强制要求从DB中访问的。

通过压力测试检测使用缓存提高的效率

相关推荐
qq_260241233 小时前
怎么检查网站CDN缓存是否生效
运维·前端·缓存
Fancier__8 小时前
Redis 缓存 + MySql 持久化 实现点赞服务
redis·mysql·缓存·增量同步·点赞
Yasen^o12 小时前
Redis高可用
数据库·redis·缓存
爱吃鱼饼的猫18 小时前
【SpringBoot篇】如何使用CommandLineRunner实现缓存预热
spring boot·spring·缓存
佩奇的技术笔记1 天前
高级:Redis 面试题精讲
数据库·redis·缓存
纪元A梦1 天前
Redis最佳实践——搜索与分类缓存详解
数据库·redis·缓存
寻梦人121381 天前
缓存工具类
java·redis·缓存
嘻嘻嘻哈哈哈嘻嘻嘻1 天前
Redis 持久化+性能管理+缓存
redis·缓存
Yasen^o1 天前
Redis-场景缓存+秒杀+管道+消息队列
数据库·redis·缓存