1、消息队列
MQ全称为Message Queue消息队列,生产者不断的往消息队列中不断写入消息,消费者则可以订阅队列中的消息,MQ是遵循了AMQP的具体实现。
AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。组件之间的解耦,消息的发送者无需知道消息使用者的存在,基于此协议的客户端与消息中间件可传递消息。
消息队列应用场景
- 异步处理、应用解耦:
- 流量削峰:服务器在接收到用户请求后,首先写入消息队列。这时如果消息队列中消息数量超过最大数量,则直接拒绝用户请求或返回跳转到错误页面(服务器熔断限流)
- 秒杀业务(缓存)根据秒杀规则读取消息队列中的请求信息,进行后续处理
2、RabbitMQ
RabbitMQ是MQ产品的典型代表。RabbitMQ 最初起源于金融系统,是一个由erlang开发的基于AMQP协议的开源实现。用于在分布式系统中存储转发消息,是当前最主流的消息中间件之一。
基本概念
1)producer指的是消息生产者,consumer消息的消费者。
2) Queue消息队列,提供了FIFO的处理机制,具有缓存消息的能力,队列消息可以设置为持久化,临时或者自动删除,决定数据是否在服务器磁盘上保留。
3) 核心概念Exchange交换机
那么为什么我们需要 Exchange 而不是直接将消息发送至队列呢?
AMQP 协议中的核心思想就是生产者和消费者的解耦,生产者从不直接将消息发送给队列。生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机。先由 Exchange 来接收,然后Exchange 按照特定的策略转发到 Queue将各个消息分发到相应的队列中。在实际应用中我们只需要定义好 Exchange 的路由策略,而生产者则不需要关心消息会发送到哪个 Queue或被哪些Consumer消费。和Queue一样,Exchange也可设置为持久化,临时或者自动删除。
不同类型的Exchange转发消息的策略有所区别:
- Direct直接交换器,Exchange会将消息发送完全匹配的队列
- 广播式交换器,不管消息的ROUTING_KEY设置为什么,Exchange都会将消息转发给所有绑定的Queue。
- topic主题交换器,工作方式类似于组播,Exchange会将消息转发和ROUTING_KEY匹配模式相同的所有队列
4) Binding
所谓绑定就是将一个特定的 Exchange 和一个特定的 Queue 绑定起来。Exchange 和Queue的绑定可以是多对多的关系
5) virtual host
相当于物理的server,可以为不同应用提供边界隔离,使得应用安全的运行在不同的vhost实例上,相互之间不会干扰。producer和consumer连接rabbit server需要指定一个vhost。
*如何保证消息100%投递的方案
- 生产端可靠性投递
- 保障消息的成功发出
- 保障MQ节点的成功接收
- 发送端收到MQ节点(Broker) 确认应答
- 完善的消息补偿机制
如果想保障消息100%投递成功,只做到前三步不一定能够保障。有些极端情况,比如生产端在投递消息时可能失败了,或者说生产端投递了消息,MQ Broker也收到了,MQ Broker在返回确认应答时,由于网络闪断导致生产端没有收到应答,此时这条消息就不知道投递成功了还是失败了,所以针对这些情况需要做一些补偿机制。
互联网大厂的解决方案:
- 消息落库,对消息状态进行打标
- 消息的延迟投递,做二次确认,回调检查
具体使用哪种要根据业务场景和并发量、数据量大小来决定
方案一:消息信息落库,对消息状态进行打标的方案如下图:
step 1:进行业务数据入库:比如发送一条订单消息,首先把业务数据也就是订单信息进行入库,然后生成一条消息,把消息也进行入库,这条消息应该包含消息状态属性,并设置初始值比如为0,表示消息创建成功