基于消息队列RabbitMq修改黑马点评

📅 发布时间:2026/7/10 13:25:12 👁️ 浏览次数:
基于消息队列RabbitMq修改黑马点评
原问题黑马点评中对于异步秒杀的实现是用redis阻塞队列优化详情看黑马点评教学组缺点1.阻塞队列会在高并发时候出现jvm内存问题2.jvm内存没有持久化机制如果服务宕机存在队列中的信息就会消失基于RabbitMq修改1.修改配置文件1.publisher-confirm-type: correlated当生产者发送消息到mq的时候mq会返回确定或者拒绝的信号保证消息可靠投递避免redis判断成功但数据库没有创建订单2.listener.simple.acknowledge-mode: manual关闭自动确认设置消费者的消息手动确认消费者会在处理完业务逻辑之后调用channel.basicAck()来告知 MQ 消息已成功处理如果消费端在处理过程中崩溃或抛出异常且未发送 ACK确认MQ 会认为消息未被处理将其重新入队。保证消费可靠避免 “消息已接收但数据库操作失败” 导致的数据不一致确保消息与业务的一致性。3.listener.simple.retry.enabled: true开启重试机制有效处理暂时性事故提高系统可用性4.max-attempts: 3最大重试次数为32.生产者当lua脚本返回结果时候对结果进行判断然后发送给消息队列3.消费者1.声明交换机和对象2.指定消费方法tag是消息的唯一标识在形参中声明spring会自动生成channelRabbitMq客户端和服务器的通道用于交互由spring自动注入basicAck确定消息basicAcklong tagboolean multiple //消息是否批量确定basicNack处理失败订单long tagboolean multipleboolean requeue//是否重新入队注意要在配置文件提前配置异常处理当前业务以及实现了消息的重试可是这样是不够的可以有如下提升1.数据回滚若还是发生数据库操作失败我们可以在catch代码块中调用rollbackRedis回滚redis保证数据库和redis的一致性2.兜底策略避免极端情况我们在数据库扣减库存中使用乐观锁避免库存超卖3.持久化我们必须先声明队列交换机消息三者的持久化缺一不可只配置队列持久化当服务宕机时候队列虽然存在交换机却删除了当生产者发送消息的时候没有找到交换机会导致消息投递失败配置队列交换机不配置消息队列和交换机虽能恢复但队列里未消费的消息会全部丢失秒杀场景会出现“消息已投递到 MQ但 MQ 宕机后未处理的订单消息丢失无法创建订单”队列持久化交换机持久化exchange Exchange(value seckillOrderExchange,type ExchangeTypes.DIRECT, durable true)消息持久化在rabbitmq配置文件中写入全局配置持久化template: message-converter: org.springframework.amqp.support.converter.Jackson2JsonMessageConverter delivery-mode: PERSISTENT# 消息持久化PERSISTENT持久化NON_PERSISTENT非持久化