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

Spring Cache + Redis 实战:手把手教你为外卖项目优化套餐查询(附完整代码)

Spring Cache + Redis 实战:手把手教你为外卖项目优化套餐查询

在"苍穹外卖"这类高并发场景下,套餐查询往往是数据库压力最大的环节之一。当用户集中访问时,频繁的数据库查询不仅会导致响应延迟,还可能引发系统雪崩。本文将带你从零开始,通过Spring Cache与Redis的深度整合,构建一套高性能的缓存解决方案。

1. 项目痛点分析与技术选型

"苍穹外卖"的套餐查询接口在高峰时段经常出现500ms以上的响应延迟,数据库监控显示CPU利用率长期维持在80%以上。通过分析发现:

  • 热点数据集中:80%的查询集中在20%的热门套餐
  • 重复查询频繁:相同套餐在1分钟内被重复查询50+次
  • 冷数据占用资源:历史套餐占用了30%的查询流量但访问量极低

针对这些问题,我们选择的技术组合是:

// 技术栈依赖配置 dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.springframework.boot:spring-boot-starter-cache' implementation 'com.github.ben-manes.caffeine:caffeine' // 二级缓存 }

技术对比表

方案吞吐量(QPS)响应时间开发复杂度适用场景
纯数据库查询120050-200ms低频访问场景
Spring Cache + Redis85005-15ms高并发热点数据
本地缓存150001-3ms极高频不变数据

2. 缓存架构设计与实现

2.1 基础环境搭建

首先在启动类启用缓存功能:

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

配置Redis连接和缓存管理器:

# application.yml spring: redis: host: 127.0.0.1 port: 6379 password: database: 0 cache: type: redis redis: time-to-live: 1800s # 默认30分钟过期 key-prefix: "CACHE_" use-key-prefix: true

2.2 核心缓存策略实现

套餐查询服务的缓存改造:

@Service @RequiredArgsConstructor public class ComboServiceImpl implements ComboService { private final ComboMapper comboMapper; @Cacheable(value = "combo", key = "#id", unless = "#result == null") public ComboVO getById(Long id) { // 数据库查询逻辑 return comboMapper.selectById(id); } @CachePut(value = "combo", key = "#combo.id") public ComboVO updateCombo(ComboDTO combo) { comboMapper.updateById(combo); return convertToVO(combo); } @CacheEvict(value = "combo", key = "#id") public void deleteCombo(Long id) { comboMapper.deleteById(id); } }

缓存注解使用技巧

  • unless参数可防止缓存空值
  • 复杂Key的生成策略:
    @Cacheable(value="combo", key="T(String).format('%d_%s',#id,#type)")
  • 条件缓存:
    @Cacheable(condition="#type.equals('hot')")

3. 高级优化策略

3.1 多级缓存架构

引入Caffeine作为本地一级缓存:

@Configuration public class CacheConfig { @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { return new CaffeineRedisCacheManager( Caffeine.newBuilder() .maximumSize(1000) .expireAfterWrite(5, TimeUnit.MINUTES), RedisCacheWriter.nonLockingRedisCacheWriter(factory), RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(30)) ); } }

3.2 缓存穿透防护

空值缓存与布隆过滤器结合:

public ComboVO getByIdWithProtection(Long id) { // 布隆过滤器预检查 if(!bloomFilter.mightContain(id)) { return null; } return cacheManager.getCache("combo").get(id, () -> { ComboVO combo = comboMapper.selectById(id); if(combo == null) { // 缓存空值防止穿透 return new NullComboVO(); } return combo; }); }

3.3 热点数据发现与预热

实现热点数据自动识别:

@Scheduled(fixedRate = 60000) public void hotDataDiscovery() { // 从Redis统计访问频次 Map<Long, Integer> accessStats = getAccessStatistics(); accessStats.entrySet().stream() .filter(e -> e.getValue() > 100) // 阈值100次/分钟 .forEach(e -> { // 主动预热到本地缓存 cacheManager.getCache("combo").get(e.getKey(), () -> comboMapper.selectById(e.getKey())); }); }

4. 性能对比与监控

4.1 压测数据对比

使用JMeter进行基准测试:

场景吞吐量(QPS)平均响应时间错误率
无缓存125078ms0.12%
基础Redis缓存820012ms0%
多级缓存142008ms0%
多级缓存+热点预热186005ms0%

4.2 监控指标配置

通过Spring Boot Actuator暴露缓存指标:

management: endpoints: web: exposure: include: health,metrics,caches metrics: tags: application: ${spring.application.name}

关键监控指标:

  • cache.gets:缓存查询次数
  • cache.hits:缓存命中率
  • cache.size:缓存元素数量

5. 生产环境最佳实践

5.1 缓存键设计规范

采用统一的命名空间:

业务模块:实体类型:ID[:子类型] 示例: order:detail:1234 user:permission:5678:menu

5.2 缓存雪崩防护

@Bean public RedisCacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheConfiguration config = RedisCacheConfiguration .defaultCacheConfig() .entryTtl(Duration.ofMinutes(30)) .computePrefixWith(name -> "takeaway::" + name + "::") .serializeValuesWith(SerializationPair.fromSerializer( new Jackson2JsonRedisSerializer<>(Object.class))); // 随机过期时间避免同时失效 return RedisCacheManager.builder(factory) .cacheDefaults(config) .withInitialCacheConfigurations(Map.of( "combo", config.entryTtl(Duration.ofMinutes(20 + new Random().nextInt(20))) )) .build(); }

5.3 大Value处理策略

对于超过10KB的套餐详情:

@Cacheable(value = "combo", key = "#id", unless = "#result == null") public ComboVO getComboDetail(Long id) { ComboDetail detail = comboMapper.selectDetailById(id); return ComboVO.builder() .id(detail.getId()) .name(detail.getName()) // 基础信息缓存 .price(detail.getPrice()) // 大字段单独存储 .descriptionCacheKey("combo:desc:" + id) .build(); } @PostConstruct public void init() { // 异步加载大字段 forkJoinPool.submit(() -> { comboMapper.selectAll().forEach(c -> redisTemplate.opsForValue().set( "combo:desc:" + c.getId(), c.getDescription() ) ); }); }

在实际项目中,这套方案使套餐查询接口的99线从原来的300ms降低到15ms以内,数据库负载下降70%。关键在于根据业务特点灵活组合各种缓存策略,而非简单套用固定模式。

http://www.jsqmd.com/news/870798/

相关文章:

  • 3小时变5分钟:如何用docx2tex彻底告别Word转LaTeX的痛苦
  • 长鑫科技295亿IPO上会,盈利拐点提前,合肥国资或迎万亿账面资产?
  • 如何快速掌握FileBrowser:面向初学者的完整Web文件管理教程
  • 2026年5月最新玉溪元江黄金回收白银回收铂金回收权威排行榜TOP5:纯金+金条+银条+钯金 门店地址联系方式推荐 - 金诚回收
  • 专业干货!AI专著写作工具推荐,一键生成20万字专著不是梦!
  • 如何用Yarn Spinner为你的游戏打造沉浸式对话体验
  • 3个真实故事告诉你:为什么你的Windows 11需要系统优化工具
  • 对比自行搭建代理Taotoken在API调用稳定性上的实际表现
  • 2026年5月最新岳阳华容黄金回收白银回收铂金回收权威排行榜TOP5:纯金+金条+银条+钯金 门店地址联系方式推荐 - 金诚回收
  • 智能安全防护识别数据集 高空作业安全带检测 安全带佩戴检测 安全带穿戴规范识别数据集 未正确佩戴安全防护措施识别 10186期
  • Mi-Create:免费开源的小米手表表盘制作终极指南
  • 当主用模型出现波动时如何利用 Taotoken 实现快速容灾切换
  • 【ChatGPT】半导体激光器深度拆解、信息图10张、爆炸图10张、C++代码框架
  • 2026年5月最新延安延长黄金回收白银回收铂金回收权威排行榜TOP5:纯金+金条+银条+钯金 门店地址联系方式推荐 - 金诚回收
  • YOLOv11农场羊只面部目标检测数据集-275张-sheep-1_2_2
  • Python 3.13字节码反编译终极指南:突破技术瓶颈的实战解决方案
  • 5分钟搞定Burp Suite中文版:让安全测试变得更简单
  • 2026年5月最新岳阳君山黄金回收白银回收铂金回收权威排行榜TOP5:纯金+金条+银条+钯金 门店地址联系方式推荐 - 金诚回收
  • 从开发者的日常痛点到流畅工作流:Simple HTTP Server如何改变你的本地开发体验
  • 5分钟永久激活IDM:免费开源脚本终极指南
  • AI专著写作必备:精选AI工具,一键炮制20万字高质量专业专著!
  • 2026年5月最新延安宜川黄金回收白银回收铂金回收权威排行榜TOP5:纯金+金条+银条+钯金 门店地址联系方式推荐 - 金诚回收
  • 2026年5月最新信阳罗山黄金回收白银回收铂金回收权威排行榜TOP5:纯金+金条+银条+钯金 门店地址联系方式推荐 - 金诚回收
  • 从玉米到水稻:如何用TO-GCN跨物种比较,快速锁定C4光合作用的关键调控因子?
  • 2026年5月最新岳阳临湘黄金回收白银回收铂金回收权威排行榜TOP5:纯金+金条+银条+钯金 门店地址联系方式推荐 - 金诚回收
  • AI技术类型谱系图:规则/机器学习/深度学习/生成式AI选型指南
  • 2026年5月最新邢台内丘黄金回收白银回收铂金回收权威排行榜TOP5:纯金+金条+银条+钯金 门店地址联系方式推荐 - 金诚回收
  • 阅读APP书源失效终极解决方案:三步快速恢复优质小说资源
  • GPT-4的1.8万亿参数与2%激活率真相:MoE架构深度解析
  • 3步实现Adobe全家桶完整激活:终极破解方案详解