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

秒杀系统主库宕机不丢单方案-05-Redis预扣+消息队列

秒杀系统主库宕机不丢单方案:Redis预扣+消息队列(流量削峰)

方案概述

Redis预扣+消息队列方案通过在应用层引入Redis缓存和消息队列,实现流量削峰和数据持久化分离。该方案从源头减少对数据库的压力,是秒杀系统主库宕机不丢单的源头减压方案。

核心原理

1. 整体架构

成功

失败

用户请求

Redis预扣库存

消息队列

异步处理

数据库持久化

返回结果

2. 工作流程

  1. Redis预扣: 用户请求先在Redis中预扣库存
  2. 消息入队: 预扣成功后,将订单信息放入消息队列
  3. 异步处理: 消费者从队列中取出消息并处理
  4. 数据库持久化: 将订单数据持久化到数据库
  5. 补偿机制: Redis和数据库数据不一致时进行补偿

3. 关键组件

  • Redis: 用于库存预扣和热点数据缓存
  • 消息队列: 用于流量削峰和异步处理
  • 补偿服务: 用于数据一致性保障

实战配置

1. Redis预扣库存

@ServicepublicclassSeckillService{@AutowiredprivateRedisTemplate<String,String>redisTemplate;@AutowiredprivateMessageQueuemessageQueue;publicbooleanpreDeductStock(LongproductId,Integerquantity){// Redis预扣库存StringstockKey="stock:"+productId;StringcurrentStock=redisTemplate.opsForValue().get(stockKey);if(currentStock==null||Integer.parseInt(currentStock)<quantity){returnfalse;}// 执行预扣Longremaining=redisTemplate.opsForValue().decrement(stockKey,quantity);if(remaining>=0){// 入队处理SeckillOrderorder=newSeckillOrder(productId,quantity);messageQueue.send(order);returntrue;}else{// 库存不足,回滚redisTemplate.opsForValue().increment(stockKey,quantity);returnfalse;}}}

2. 消息队列配置

@ConfigurationpublicclassMessageQueueConfig{@BeanpublicQueueseckillQueue(){returnnewQueue("seckill_queue",true);}@BeanpublicMessageSendermessageSender(){returnnewMessageSender();}}@ServicepublicclassMessageSender{@AutowiredprivateAmqpTemplaterabbitTemplate;publicvoidsend(SeckillOrderorder){rabbitTemplate.convertAndSend("seckill_exchange","seckill_routing_key",order);}}

3. 消费者处理

@ComponentpublicclassSeckillConsumer{@AutowiredprivateOrderServiceorderService;@RabbitListener(queues="seckill_queue")publicvoidhandleSeckillOrder(SeckillOrderorder){try{// 数据库持久化orderService.createOrder(order);}catch(Exceptione){// 记录失败,后续补偿compensationService.recordFailedOrder(order);}}}

4. 补偿机制

@ServicepublicclassCompensationService{@AutowiredprivateRedisTemplate<String,String>redisTemplate;@AutowiredprivateOrderDaoorderDao;@Scheduled(fixedDelay=60000)publicvoidcompensateOrders(){List<SeckillOrder>failedOrders=orderDao.selectFailedOrders();for(SeckillOrderorder:failedOrders){try{// 重新处理订单orderService.createOrder(order);// 标记为已处理orderDao.updateOrderStatus(order.getId(),"COMPLETED");}catch(Exceptione){// 继续保留失败状态,等待下次重试}}}}

优缺点分析

优点

  • 流量削峰: Redis缓存有效减少数据库压力
  • 性能提升: 读写分离,提高系统吞吐量
  • 容灾能力强: Redis和数据库分离,单点故障影响小
  • 扩展性好: 支持水平扩展

缺点

  • 数据一致性: 需要补偿机制保证最终一致性
  • 实现复杂: 需要多个组件协同工作
  • 运维成本: 需要维护Redis和消息队列

适用场景

  1. 超高并发秒杀系统: 并发量在50000+ QPS
  2. 读多写少场景: 如商品库存查询、订单创建
  3. 已有缓存和消息队列基础设施

实战案例

某手机厂商新品秒杀活动

  • 场景: 新品发布会,预计并发量100000 QPS
  • 配置:
    • Redis集群预扣库存
    • RabbitMQ消息队列
    • 5个消费者节点
    • 补偿机制重试3次
  • 效果:
    • 零数据丢失,成功保障订单不丢单
    • 平均响应时间50ms
    • 系统吞吐量90000 QPS
    • Redis命中率99.9%

最佳实践

  1. Redis集群: 使用Redis Cluster提高可用性和性能
  2. 消息持久化: 确保消息队列支持持久化
  3. 幂等设计: 确保消息处理的幂等性
  4. 监控告警: 建立全面的监控体系

Redis集群配置示例

# redis.confcluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes appendfsync everysec

监控指标

-- Redis监控INFO memory INFOreplicationINFO cluster-- 消息队列监控rabbitmqctl list_queues name messages_ready messages_unacknowledged-- 数据库监控SHOWGLOBALSTATUSLIKE'Innodb_%';

注意事项

  1. Redis持久化: 配置合适的持久化策略
  2. 消息顺序: 确保消息处理的顺序性
  3. 数据一致性: 建立完善的补偿机制
  4. 容量规划: 合理规划Redis和消息队列容量

总结

Redis预扣+消息队列方案通过流量削峰和数据持久化分离,实现了秒杀系统主库宕机不丢单的源头减压方案。该方案在超高并发场景下表现优异,能够有效减少数据库压力,提高系统吞吐量。建议结合Redis集群和消息队列的最佳实践,确保系统的稳定性和可靠性。

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

相关文章:

  • 香橙派Zero/PC双板实测:一篇搞定Ubuntu镜像下载、烧录与首次SSH连接
  • S32K3XX外设时钟配置详解:以UART1为例,手把手教你算波特率(EB配置全流程)
  • 高中学历快递小哥成功转行数据分析师,CDA数据分析师备考经验
  • Gophish密码重置全攻略:从SQLite操作到密码哈希替换
  • 从赛车标志到掌心强芯:F1中国站上的骁龙印记
  • STM32时钟配置避坑指南:HSE旁路模式与有源晶振实战解析
  • Phi-4-mini-reasoning惊艳案例:多约束逻辑题(时间/空间/因果)联合推理输出
  • 用PyTorch和MNIST数据集,手把手教你复现CGAN生成指定数字(附完整代码)
  • 深入UDS诊断刷写:对比DoCAN与DoIP在实车OTA中的完整流程与信号分析
  • Bash脚本实战:5个超实用的.sh文件编写技巧(附代码示例)
  • DOL-CHS-MODS整合包全攻略:从零基础到个性化定制
  • OpenCore Legacy Patcher:让老旧Mac重生的系统焕新工具
  • 【圆环阵列】HFSS圆环阵列【含Matlab源码 15259期】
  • 实测16公里无人机WiFi图传模块:如何在山地救援中实现零延迟高清回传?
  • 别再只盯着YOLO了!传统OpenCV轮廓检测+单目测距,在边缘设备上也能跑出高精度
  • 用STM32CubeMX和HAL库搞定编码电机测速:从定时器编码器模式到转速计算全流程
  • BlenderUSDZ:实现3D模型AR化的高效解决方案
  • 3步实现AI智能背景移除:开源工具让透明GIF制作变得如此简单
  • 不止于去广告:在UOS上配置AdGuardHome,解锁安全搜索、家长控制和防DNS劫持的全家桶网络守护
  • Cesium影像图层实战:从ImageryLayer到ImageryProvider的完整配置指南(附常见问题解决)
  • 语雀文档批量导出终极指南:快速备份你的创作内容
  • AUBO i5机械臂手眼标定后,如何让末端执行器稳定跟踪移动的ArUco码?
  • 三菱PLC GXWorks2实战:基于SFC的红绿灯控制系统设计与优化
  • 玩转ESP32-S3调试:GDB高级命令与自定义调试技巧大全
  • 梅奔银箭与高通骁龙:从W14到上海冠军的极速共振
  • Qwen3.5-9B-AWQ-4bit开源模型部署实战:CSDN GPU平台一键拉起视觉理解服务
  • AI金融分析与智能交易决策:TradingAgents-CN多智能体协作框架全解析
  • 通义千问Embedding模型响应慢?批处理优化提速50%实战
  • 如何突破智能音箱音乐限制?开源方案XiaoMusic让小爱音箱播放任意歌曲
  • 从一道“挣值计算”真题出发,手把手教你用Excel搞定项目成本进度分析