使用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中访问的。

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

相关推荐
Fly不安全17 小时前
Web安全:缓存欺骗攻击;基于缓存、CDN的新型Web漏洞
nginx·web安全·缓存·web·cdn·缓存欺骗攻击
阿猿收手吧!17 小时前
【Redis】Redis入门以及什么是分布式系统{Redis引入+分布式系统介绍}
数据库·redis·缓存
落霞的思绪17 小时前
Redis实战(黑马点评)——涉及session、redis存储验证码,双拦截器处理请求
spring boot·redis·缓存
Sunny_lxm18 小时前
<keep-alive> <component ></component> </keep-alive>缓存的组件实现组件,实现组件切换时每次都执行指定方法
前端·缓存·component·active
web2u20 小时前
MySQL 中如何进行 SQL 调优?
java·数据库·后端·sql·mysql·缓存
Yeats_Liao20 小时前
Spring 框架:配置缓存管理器、注解参数与过期时间
java·spring·缓存
小金的学习笔记21 小时前
RedisTemplate和Redisson的使用和区别
数据库·redis·缓存
呼啦啦啦啦啦啦啦啦21 小时前
【Redis】事务
数据库·redis·缓存
猿小飞1 天前
redis 5.0版本和Redis 7.0.15的区别在哪里
数据库·redis·缓存
qq_392794481 天前
前端缓存策略:强缓存与协商缓存深度剖析
前端·缓存