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

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

相关推荐
全栈弄潮儿²⁰²⁴3 天前
AI Agent 开发实战(30):限流、缓存与成本控制
人工智能·gpt·缓存·agent·限流·agi·成本控制
Together_CZ4 天前
DeepSeek-V4.1-Flash:Pushing the Limits of KV Cache Compression——推动 KV 缓存压缩的极限
缓存·llm·compression·kv cache·deepseek·v4.1-flash·推动 kv 缓存压缩的极限
Pioneer000015 天前
我用 Redis + 网关做多模型 API 路由:缓存命中率 95%+ 的工程实践
人工智能·redis·后端·缓存·性能优化·架构
hweiyu005 天前
Redis命令:MSETNX
redis·缓存
wdfk_prog5 天前
ROS教程08:从 TransportTCP::connect() 追到 TCPROS Connection Header、序列化与 Socket 数据传输
运维·缓存·docker·容器·ros
是Dream呀5 天前
Harness 工程:让 Agent 真正把任务做完
人工智能·分布式·缓存·agent
努力努力再努力wz6 天前
【Redis进阶系列】:从主从复制到 Sentinel,一文建立故障检测、Leader 选举与 Failover 的完整心智模型
数据库·redis·缓存
wdfk_prog6 天前
ROS教程10:从 gtest 到 rostest——Unit Test、Node 集成测试、rosbag 与 rqt 验证闭环
运维·缓存·docker·容器·ros
程序猿乐锅7 天前
【黑马点评 | 第四篇】Redis缓存雪崩
java·数据库·spring boot·redis·缓存
HanhahnaH7 天前
Redis单线程和Tair多线程架构设计对比
分布式·缓存