RabbitMQ实现对秒杀步骤的异步解耦

RabbitMQ基础知识

生产者和消费者是什么?

        生产者:生产者负责创建并发送消息到消息队列。它连接到RabbitMQ服务器,通过Queue(队列)对象发布消息。生产者可以一次性发送一条或多条消息,并可以选择是否立即确认发送成功。如果发生错误,生产者通常会自动重试或者回滚操作。

        消费者:消费者从消息队列中接收并处理消息。它们连接到相同的队列,然后监听队列中的消息。当有新的消息可用时,消费者会消费这些消息,处理完毕后再将消息标记为已消费。消费者可以有多个实例同时运行,这样可以实现负载均衡。

消息的发布订阅模式有哪些?

        临时订阅:只有消费者启动并且运行的时候才存在。一旦消费者退出,相应的订阅以及尚未处理的消息就会丢失。

        持久订阅:订阅会一直存在除非主动去删除。消费者退出后,消息系统会继续维护该订阅,并且后续消息可以被继续处理。

rabbitmq如何保证消息的可靠性?

        消息发送:confirm机制。解决了事务性能问题(事务机制是同步的,提交一个事务之后会阻塞,但是 confirm 机制是异步的)在生产者开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如果写入了rabbitmq之中,rabbitmq会给你回传一个ack消息;如果rabbitmq没能处理这个消息,会回调一个nack接口,消息失败进行重试。

        队列持久化:开启rabbitMQ的持久化机制。把消息持久化到硬盘上,这样即使rabbitMQ挂掉在重启后仍然可以从硬盘读取消息;

        消息消费:ACK确认机制。通过手动ack来保证消费者主动的控制ack行为,避免业务异常导致消息丢失的情况。

消息队列mq消息重复现象怎么出现的,怎么解决

        防止重复消费可以将接口设计成幂等性的。比如扣除库存的时候,带上唯一的订单号和状态标志,消费到这个消息的时候先去redis里查一下之前消费过没有,消费过就不处理。

什么是 AMQP?

        AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。Erlang中的实现有RabbitMQ等。

        AMQP 基于TCP协议之上再次封装的协议,AMQP定义了合适的服务器端域模型,规范服务器的行为(AMQP的服务器端称broker)

SpringAMQP

        SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,为面向消息的中间件设计。

( 官方地址:https://spring.io/projects/spring-amqp

SpringAMQP提供了三个功能:

        - 自动声明队列、交换机及其绑定关系
        - 基于注解的监听器模式,异步接收消息
        - 封装了RabbitTemplate工具,用于发送消息 

Exchange(交换机) 和 Queue (队列)

        Exchange接收Producer发送的Message。根据不同的路由算法,将Message发送给Message Queue.

        Queue 在 Message没有被 Consumer消费时,缓存这些Message,具体的缓存策略由实现者决定。当Queue 与Consumer之间连接畅通时,Queue 则需要将消息转发给 Consumer进行消费

项目整合消息队列实现秒杀优化

1.消息队列环境搭建

        创建一个direct类型【完全匹配】的交换机以及一个消息队列,然后将二者绑定。之后发往该交换机的消息都会转发到消息队列。

2.修改秒杀下单业务

        在认定有抢购资格后,直接向seckill.direct交换机发送消息,内容包含voucherId、userId、orderId。

//3.走到这一步说明有购买资格,将订单信息存到阻塞队列
VoucherOrder voucherOrder = new VoucherOrder();
long orderId = redisIdWorker.nextId("order");
voucherOrder.setId(orderId);
voucherOrder.setUserId(UserHolder.getUser().getId());
voucherOrder.setVoucherId(voucherId);
//存入消息队列等待异步消费
rabbitTemplate.convertAndSend("seckill.direct","seckill.order",voucherOrder);
4.监听秒杀成功订单

        用@RabbitListener注解创建一个监听器,监听消息队列,当有消息发送过来的时候就执行业务逻辑创建订单到数据库中。(先开启手动提交,否则业务执行失败,监听到的消息就丢失了)

rabbitmq:
host: 120.26.122.127
port: 5672
listener:
  simple:
    acknowledge-mode: manual
@Autowired
VoucherOrderServiceImpl voucherOrderService;
@RabbitListener(queues = {"seckill.order.queue"})
public void recieveMessage(Message message, Channel channel, VoucherOrder voucherOrder){
    try {
        voucherOrderService.handleVoucherOrder(voucherOrder);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

测试
      测试1000个人在一秒内同时下单,观察是否发生超卖,并且记录系统性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值