架构实战篇:Spring Boot 多缓存实战

前言

一个程序少不了对数据库的增删改查操作,我们也知道内存的速度是大大快于硬盘的速度的。当我们需要重复地获取相同的数据的时候,我们一次又一次的请求数据库或者远程服务,导致大量的时间耗费在数据库查询或者远程方法调用上,程序性能也就大打折扣,这便是数据缓存要解决的问题。

Spring boot 给我们提供了便利的缓存注解,也大大了减少了系统的耦合

需要解决的问题

怎么用缓存减少一对多关系的频繁数据库访问

怎么用缓存解决高并发的数据服务性能

下面给出一些源码和讲解

目录结构

项目依赖配置

pom.xml

实体类

为了方便测试我们直接使用了 mysql 自带的表, 注意这里的 toString 方法需要重写下,后面会用作缓存的Key

HelpTopic.java

关系实体类

HelpCategory.java

Category 业务层缓存配置

思路:把每个实体都跟表关系起来,相当于表数据的缓存,value 也跟表名一样,这里主要解决第1个问题

@Cacheable(key = "#id", value = "help_category")

@CacheEvict(key = "#id", value = "help_category")

Topic 业务层缓存配置

这里的 selectList 方法循环的去查询分类对象信息,相同的分类其实都是直接存内存中取的

Web服务配置

@Cacheable(key = "'dataGrid' + #form.toString()", value = "HelpTopicController", sync = true)

这里主要解决第二个问题,当很多用户在3秒之内都请求了同样的服务,将会直接返回缓存的结果,而不再执行 selectList 的数据库查询

缓存管理配置

Spring boot 提供了 CacheManager 用来管理所有的缓存

这里我们声明了以下缓存

new ConcurrentMapCache("help_category")

new ConcurrentMapCache("help_topic")

new CaffeineCache("HelpTopicController", Caffeine.newBuilder()

.expireAfterWrite(3, TimeUnit.SECONDS)

.build())

new CaffeineCache("HelpCategoryController", Caffeine.newBuilder()

.expireAfterWrite(3, TimeUnit.SECONDS)

.build())

前两个主要是基于内存长时间缓存的,不需要经常更新

后两个主要是解决并发请求的缓存,所以是用了 CaffeineCache 的缓存策略 expireAfterWrite 3 秒内数据没有更新就删除缓存数据, 可以理解为是数据会在缓存中存在 3 秒钟

高并发测试

测试场景 100 个线程,每个线程请求100次

不使用缓存

使用缓存后

可以看出平均响应时间提高了 14 倍多

一般情况下这样就够了,但是实际项目当中还要根据不同的项目架构,以及不同的业务场景来决定该用什么样解决方案

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180806G1DTOJ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券