RabbitMQ的介绍
RabbitMQ是一个流行的开源消息队列系统,它允许应用程序之间进行异步通信和数据传输。它支持多种消息传递协议,如AMQP,STOMP和MQTT等。RabbitMQ具有可靠性高,可扩展性好,高可用性等优点,被广泛应用于各种领域,如金融,电信,物联网等。
什么是消息中间件?
MQ全称为Message Queue,消息队列是应用程序和应用程序之间的通信方法。
为什么使用mq? 在项目中,可将一些无需即时返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
一、消息中间件初步
1.1 RabbitMQ有什么特点/好处
-
应用解耦
- 在生产者与消费者模型中,mq相当于是一个中间商,可以将消息发送到不同的微服务中,更好的跟应用进行解耦。
-
异步提速
- 当使用了mq后,我们在生产者中,发送一条消息到mq中,比如减库存操作。发送完这条消息后直接返回给我们的前台,说明下单已经成功。后面的各个微服务会接收到消息,做相应的处理。
-
削峰填谷
- 如订单系统,在下单的时候就会往数据库写数据。但是数据库只能支撑每秒1000左右的并发写入,并发量再高就容易宕机。低峰期的时候并发也就100多个,但是在高峰期时候,并发量会突然激增到5000以上,这个时候数据库肯定卡死了。
- 消息被MQ保存起来了,然后系统就可以按照自己的消费能力来消费,比如每秒1000个数据,这样慢慢写入数据库,这样就不会卡死数据库了。
1.2 MQ劣势
- 系统可用性降低
系统引入的外部依赖越多,系统稳定性越差。一旦 MQ 宕机,就会对业务造成影响。如何保证MQ的高可用?
- 系统复杂度提高
MQ 的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过 MQ 进行异步调用。如何
保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?
- 一致性问题
A 系统处理完业务,通过 MQ 给B、C、D三个系统发消息数据,如果 B 系统、C 系统处理成功,D 系统处理
失败。如何保证消息数据处理的一致性。
使用mq中只能保证最终一致性。
1.3 RabbitMQ工作原理
-----服务启动-----
1、 启动Broker中的rabbitmq程序
2、 建立exchange交换机
3、 通过交换机把消息分发到队列中,exchange由绑定关系,决定分发到一个或多个队列中
-----发送消息-----
1、生产者和Broker建立TCP连接。长连接
2、生产者和Broker建立通道change。
3、生产者通过通道change把消息发送给Broker,由Exchange将消息进行转发。
4、Exchange将消息转发到指定的Queue(队列)
----接收消息-----
1、消费者和Broker建立TCP连接
2、消费者和Broker建立通道
3、消费者监听指定的Queue(队列)
4、当有消息到达Queue时Broker默认将消息推送给消费者。
5、消费者接收到消息。
1.4 RabbitMQ的工作模式
二、消息中间件高级
2.1 消息可靠性投递
在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。
- confirm 确认模式 保证的是这个消息发送到交换机了。confirm机制会告诉你消息到了交换机没有
- return 退回模式 这个消息到了交换机之后,mq是否把消息分发到队列上。如果没有分发到队列上,比如routingKey写错了,return模式会告诉你发送失败了
- 同时在交换机和队列也可以做持久化保证消息的可用性
2.2 Consumer ACK
ack指 Acknowledge,确认。 表示消费端收到消息后的确认方式。
有三种确认方式:
• 自动确认:acknowledge="none"
• 手动确认:acknowledge="manual"
• 根据异常情况确认:acknowledge="auto"
其中自动确认是指,当消息一旦被Consumer接收到,则自动确认收到,并将相应 message 从 RabbitMQ 的消息缓存中移除。但是在实际业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会丢失。
如果设置了手动确认方式,则需要在业务处理成功后,调用channel.basicAck(),手动签收,如果出现异常,则调用channel.basicNack()方法,让其自动重新发送消息。
消费完消息之后,手动调用ack机制,就可以避免消息,未处理完就自动确认,从而导致消息丢失。
2.3 TTL 超时删除消息
TTL 全称 Time To Live(存活时间/过期时间)。当消息到达存活时间后,还没有被消费,会被自动清除。 RabbitMQ可以对消息设置过期时间,也可以对整个队列(Queue)设置过期时间。
2.4 死信队列
死信队列,英文缩写:DLX 。Dead Letter Exchange(死信交换机),当消息成为Dead message死信消息后,可以被重新发送到另一个交换机,这个交换机就是DLX。
消息成为死信的三种情况:
- 队列消息长度到达限制;
- 消费者拒接消费消息,basicNack/basicReject,并且不把消息重新放入原目标队列,requeue=false;
- 原队列存在消息过期设置,消息到达超时时间未被消费;
2.5延迟队列
延迟队列,即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费。
提出需求:
- 下单后,30分钟未支付,取消订单,回滚库存。
- 新用户注册成功7天后,发送短信。
TTL+死信队列 组合实现延迟队列的效果。