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

张开发
2026/5/21 11:41:49 15 分钟阅读
秒杀系统主库宕机不丢单方案-05-Redis预扣+消息队列
秒杀系统主库宕机不丢单方案Redis预扣消息队列流量削峰方案概述Redis预扣消息队列方案通过在应用层引入Redis缓存和消息队列实现流量削峰和数据持久化分离。该方案从源头减少对数据库的压力是秒杀系统主库宕机不丢单的源头减压方案。核心原理1. 整体架构成功失败用户请求Redis预扣库存消息队列异步处理数据库持久化返回结果2. 工作流程Redis预扣: 用户请求先在Redis中预扣库存消息入队: 预扣成功后将订单信息放入消息队列异步处理: 消费者从队列中取出消息并处理数据库持久化: 将订单数据持久化到数据库补偿机制: Redis和数据库数据不一致时进行补偿3. 关键组件Redis: 用于库存预扣和热点数据缓存消息队列: 用于流量削峰和异步处理补偿服务: 用于数据一致性保障实战配置1. Redis预扣库存ServicepublicclassSeckillService{AutowiredprivateRedisTemplateString,StringredisTemplate;AutowiredprivateMessageQueuemessageQueue;publicbooleanpreDeductStock(LongproductId,Integerquantity){// Redis预扣库存StringstockKeystock:productId;StringcurrentStockredisTemplate.opsForValue().get(stockKey);if(currentStocknull||Integer.parseInt(currentStock)quantity){returnfalse;}// 执行预扣LongremainingredisTemplate.opsForValue().decrement(stockKey,quantity);if(remaining0){// 入队处理SeckillOrderordernewSeckillOrder(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(queuesseckill_queue)publicvoidhandleSeckillOrder(SeckillOrderorder){try{// 数据库持久化orderService.createOrder(order);}catch(Exceptione){// 记录失败后续补偿compensationService.recordFailedOrder(order);}}}4. 补偿机制ServicepublicclassCompensationService{AutowiredprivateRedisTemplateString,StringredisTemplate;AutowiredprivateOrderDaoorderDao;Scheduled(fixedDelay60000)publicvoidcompensateOrders(){ListSeckillOrderfailedOrdersorderDao.selectFailedOrders();for(SeckillOrderorder:failedOrders){try{// 重新处理订单orderService.createOrder(order);// 标记为已处理orderDao.updateOrderStatus(order.getId(),COMPLETED);}catch(Exceptione){// 继续保留失败状态等待下次重试}}}}优缺点分析优点流量削峰: Redis缓存有效减少数据库压力性能提升: 读写分离提高系统吞吐量容灾能力强: Redis和数据库分离单点故障影响小扩展性好: 支持水平扩展缺点数据一致性: 需要补偿机制保证最终一致性实现复杂: 需要多个组件协同工作运维成本: 需要维护Redis和消息队列适用场景超高并发秒杀系统: 并发量在50000 QPS读多写少场景: 如商品库存查询、订单创建已有缓存和消息队列基础设施实战案例某手机厂商新品秒杀活动场景: 新品发布会预计并发量100000 QPS配置:Redis集群预扣库存RabbitMQ消息队列5个消费者节点补偿机制重试3次效果:零数据丢失成功保障订单不丢单平均响应时间50ms系统吞吐量90000 QPSRedis命中率99.9%最佳实践Redis集群: 使用Redis Cluster提高可用性和性能消息持久化: 确保消息队列支持持久化幂等设计: 确保消息处理的幂等性监控告警: 建立全面的监控体系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-- 数据库监控SHOWGLOBALSTATUSLIKEInnodb_%;注意事项Redis持久化: 配置合适的持久化策略消息顺序: 确保消息处理的顺序性数据一致性: 建立完善的补偿机制容量规划: 合理规划Redis和消息队列容量总结Redis预扣消息队列方案通过流量削峰和数据持久化分离实现了秒杀系统主库宕机不丢单的源头减压方案。该方案在超高并发场景下表现优异能够有效减少数据库压力提高系统吞吐量。建议结合Redis集群和消息队列的最佳实践确保系统的稳定性和可靠性。

更多文章