当前位置: 首页 > news >正文

Redis缓存优化

一. 场景分析

为了优化系统的响应速度,对于那些访问频率高但更新频率低的数据,使用缓存可以显著减少数据库查询次数,提升用户体验。

这里以主页精选应用为例,具体就是缓存前十页的精选应用列表数据。因为精选应用的更新频率相对较低。

这种场景下我们采用最主流的旁路缓存模式:查询时先查询缓存,命中则直接返回。未命中则查询数据库,返回数据并将其写入缓存。设置合理的过期时间,无需手动删除缓存。

二. 开发实现

1. 引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>3.1.3</version> <!-- 此处版本号可根据实际需求调整,比如Spring Boot 3.1.x系列 -->
</dependency>

2.检查配置文件中的Redis连接信息

spring:data:redis:host: localhostport: 6379database: 0password:ttl: 3600  # 缓存过期时间(秒)

3.. 缓存key生成工具类

3.1 给出查询精选应用的接口方法:

/*** 分页获取精选应用列表** @param appQueryRequest 查询请求* @return 精选应用列表*/@PostMapping("/good/list/page/vo")public BaseResponse<Page<AppVO>> listGoodAppVOByPage(@RequestBody AppQueryRequest appQueryRequest) {}

3.2 AppQueryRequest请求类:

@EqualsAndHashCode(callSuper = true)
@Data
public class AppQueryRequest extends PageRequest implements Serializable {/*** id*/private Long id;/*** 应用名称*/private String appName;/*** 代码生成类型(枚举)*/private String codeGenType;/*** 优先级*/private Integer priority;/*** 创建用户id*/private Long userId;private static final long serialVersionUID = 1L;
}

这里可以看到查询请求类有多个字段,如果用户每次的查询条件不同,生成的AppqueryRequest也是不同的。为了生成一致且唯一的缓存键。缓存键的生成思路是将复杂的对象转换为固定长度的哈希值。这样相同的查询条件生成的缓存key是相同的,保证了不同查询请求的key唯一,又避免了key过长的问题。

3.3 key生成工具类:

/*** 缓存 key 生成工具类** @author yupi*/
public class CacheKeyUtils {/*** 根据对象生成缓存key (JSON + MD5)** @param obj 要生成key的对象* @return MD5哈希后的缓存key*/public static String generateKey(Object obj) {if (obj == null) {return DigestUtil.md5Hex("null");}// 先转JSON,再MD5String jsonStr = JSONUtil.toJsonStr(obj);return DigestUtil.md5Hex(jsonStr);}
}

这个工具类主要使用 Hutool 工具库实现,几个要点:

   1.JSON 序列化: 确保对象内容的一致性,相同内容的对象生成相同的字符串

   2.MD5 哈希: 将长字符串转换为固定长度的字符串,避免 Redis key 过长

   3.边界处理: 正确处理 null 值和空参数的情况

4. 启用缓存功能

再Spring Boot 启动类上添加 @EnableCaching 注解,支持 Spring Data 缓存注解。

@SpringBootApplication
@EnableCaching
public class SzjAiCodeApplication {public static void main(String[] args) {SpringApplication.run(SzjAiCodeApplication.class, args);}}

5. 配置缓存管理器

必须配置 Redis 缓存管理器 CacheManager,这是 Spring Cache 的核心组件。如果不配置的话,使用缓存注解时可能会报错。

/*** Redis 缓存管理器配置*/
@Configuration
public class RedisCacheManagerConfig {@Resourceprivate RedisConnectionFactory redisConnectionFactory;@Beanpublic CacheManager cacheManager() {// 配置 ObjectMapper 支持 Java8 时间类型ObjectMapper objectMapper = new ObjectMapper();objectMapper.registerModule(new JavaTimeModule());
//        // 默认类型配置:启用默认类型信息(针对非final类),以便反序列化时能恢复原类型
//        objectMapper.activateDefaultTyping(
//                objectMapper.getPolymorphicTypeValidator(),
//                ObjectMapper.DefaultTyping.NON_FINAL
//        );// 默认配置RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)) // 默认 30 分钟过期.disableCachingNullValues() // 禁用 null 值缓存// key 使用 String 序列化器.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));//不打开即使用redis的默认序列化器
//                // value 使用 JSON 序列化器(支持复杂对象)但是要注意开启后需要给序列化增加默认类型配置,否则无法反序列化
//                .serializeValuesWith(RedisSerializationContext.SerializationPair
//                        .fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)));
//return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(defaultConfig)// 针对 good_app_page 配置5分钟过期.withCacheConfiguration("good_app_page",defaultConfig.entryTtl(Duration.ofMinutes(5))).build();}
}

这个配置的几个关键点:

1. 序列化器选择: StringRedisSerializer 用于序列化 key,确保 Redis 中的 key 是可读的字符串;GenericJackson2JsonRedisSerializer 用于序列化 value,支持复杂对象的序列化和反序列化。

2. 时间类型支持: 注册 JavaTimeModule 来支持 Java 8 时间类型 LocalDateTime

3. 差异化配置: 既提供了默认配置,又为特定的缓存区域设置不同的过期时间

但是要注意,如果对 value 进行 JSON 序列化,可能会出现无法反序列化的情况,因为 Redis 中并没有存储 Java 类的信息,不知道要反序列化成哪个类,就会报错。所以我们可以先注释掉这些代码,使用redis默认的序列化器。

如果一定要对 value 进行 JSON 序列化,则开启默认类型配置,并且要反序列化的对象一定要有无参构造方法。

6. 应用缓存注解

在接口方法上添加缓存注解:

@PostMapping("/good/list/page/vo")
@Cacheable(value = "good_app_page",key = "T(com.yupi.yuaicodemother.utils.CacheKeyUtils).generateKey(#appQueryRequest)",condition = "#appQueryRequest.pageNum <= 10"
)
public BaseResponse<Page<AppVO>> listGoodAppVOByPage(@RequestBody AppQueryRequest appQueryRequest) {// 方法实现保持不变...
}

这里使用了 SpEL(Spring Expression Language)表达式:

 T(类名):用于调用静态方法,生成缓存 key

 #参数名:用于引用方法参数

 condition:设置缓存条件,只有前 10 页才会被缓存

缓存注解的工作原理,执行流程如下:

1. 方法执行前:Spring 根据 key 表达式生成缓存键

2. 缓存检查:检查 Redis 中是否存在该键对应的缓存数据

3. 缓存命中:如果存在且未过期,直接返回缓存数据,不执行方法

4. 缓存未命中:如果不存在,执行方法获取结果,并将结果存储到 Redis 中 5. 返回结果:返回方法执行结果

http://www.dtcms.com/a/435641.html

相关文章:

  • 新手freertos 移植及其注意事项(chatgpt)
  • 东莞网站设计精英成都大丰网站建设
  • 国外大型网站荣耀手机官网
  • 网站资质证书网站时间轴
  • 长春在线制作网站网页设计速成培训
  • seo优化网站排名假冒网站能通过备案登记吗
  • 企业策划书行者seo
  • 做词云的网站建设网站的费用如何账务处理
  • 宁波网站推广公司有哪些后台网站下载
  • QT肝8天09--用户列表
  • 温州阀门网站建设河北建设工程信息网招聘网
  • 聚成网站建设公众平台微信公众号官网
  • 题库批量(文件)导入的全链路优化实践
  • 天津的网站建设公司个人网站不备案做经营性质网站
  • 无锡中英文网站建设青岛做网络推广的公司有哪些
  • Azure - Azure需要MFA login了(2025-09-30之后)
  • List迭代器和模拟(迭代器的模拟)
  • 安卓手机做网站服务器全国十大软件开发培训机构
  • 周口网站制作哪家好邢台seo关键词引流
  • 上海网络公司网站环保类网站模板免费下载
  • 移动商务网站开发课程ppt设计培训班
  • 专门做外包的网站简诉网站建设的基本流程
  • 黄浦区未成年人思想道德建设网站传统营销与网络营销的区别
  • 网站的功能和特色响应式网站的开发
  • 如何在企业系统作系统中使用命令提示符查找 PowerEdge 服务编号
  • vue3中选项式 api 、组合式 api能能否混用
  • 汕头企业网站建设价格如何建设网站使用
  • 做电影网站需要多打了服务器湖北省建设厅造价官方网站
  • 哪里有做装修网站网上家教网站开发
  • 电商推广费用占比汕头网站快速排名优化