RabbitMQ
1. MQ
MQ全称为Message Queue,即消息队列。“消息队列”是在消息的传输过程中保存消息的容器。它是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。
2. 认识RabbitMQ
RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。
3. 常见的MQ产品
- Kafka:分布式消息系统,高吞吐量(大数据使用)
- ActiveMQ:基于JMS
- RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好
- RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会
3.1 各类产品比较
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
开发语言 | java | erlang | java | scala |
单机吞吐量 | 万级 | 万级 | 10万级 | 10万级 |
时效性 | ms级 | us级 | ms级 | ms级以内 |
可用性 | 高(主从架构) | 高(主从架构) | 非常高(分布式架构) | 非常高(分布式架构) |
功能特性 | 成熟的产品,在很多公司得到应用,有较多的文档;各种协议支持较好 | 基于erlang开发,所以并发能力很强,性能极其好,延时很低;管理界面较丰富 | MQ功能比较完备,扩展性佳 | 只支持主要的MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据准备的,在大数据领域应用广。 |
4. 工作模式
4.1 单发送单接收(简单队列模式)
简单的发送与接收,没有特别的处理。
4.2 单发送多接收(工作队列模式)
-
一个生产者,多个消费者;且一条消息只能被一个消费者消费,不能被多个消费者重复消费;
-
RabbitMQ默认的分发机制:轮询分发,默认情况下RabbitMQ会将接收到的消息逐个分发给消费者,并且是一次性分发完,它不等你,它就轮询发,你处理的慢就给你堆在那里自己慢慢去处理。
-
这显然不是我们想要的。我们想要的是,给处理的慢的消费者少发点,给处理的快的消费者多发点,这样可以不让消息在消费端造成堆积。这里我们做一个简单的配置,模拟能者多劳的“公平模式”。
-
设置prefetch=1,它表示限制每个Consumer在同一个时间点最多只能处理一个消息,我手里的活还没干完的话你就不能再给我分了。
spring:
rabbitmq:
host: localhost
port: 5672
username: sunxuchao
password: 123456
virtual-host: sunxuchao
listener:
simple:
# 公平分发
prefetch: 1
4.3 Publish/Subscribe(发布、订阅模式)
发送端发送广播消息,多个接收端接收。使用"fanout"方式发送,即广播消息,发送端不需要关心谁接收,一个队列可以有多个消费者,不用指定routing key,但发送到队列的消息只能被其中一个消费。
4.4 Routing (路由模式)
- 发送端按routing key发送消息,不同的接收端按不同的routing key接收消息。
- 多个队列使用相同的绑定键是合法的。我们可以添加一个 X 和 Q1 之间的绑定,使用 black 绑定键。这样一来,直连交换机就和扇型交换机的行为一样,会将消息广播到所有匹配的队列。带有 black 路由键的消息会同时发送到 Q1 和 Q2队列中。
4.5 Topics(主题模式)
-
发送端不只按固定的routing key发送消息,而是按字符串“匹配”发送,接收端同样如此。
-
一个队列可以有多个消费者,但发送到队列的消息只能被其中一个消费。
-
topic 模式中Routing key必须具有固定的格式:以 . 间隔的一串单词
-
*可以替代一个单词,# 可以替代 0 或多个单词
5. RabbitMQ 的优点
- 基于AMQP协议、通过插件还支持JMS标准
- 高并发、高性能、高可用
- 强大的社区支持、高热度,很多大型公司都在使用(美团、滴滴、去哪、头条)
- 支持开发语言众多。支持插件
- 它是目前应用相当广泛的消息中间件,在企业级应用、微服务应用中,它起到了一个非常重要的角色。
- 在业务服务模块中解耦、异步通信、高并发限流、超时业务、数据延迟处理等都可以使用RabbitMQ。
- 可以用于不同开发语言开发应用间的通信,实现企业应用的集成。适合作为多个应用之间松耦合的接口,且不需要发送方和接收方同时在线。不用语言的软件解耦,可以最大限度的减少程序间的互相依赖,提高了系统的可用性和扩展性,同时还增加了消息的可靠传递和事务管理的功能。
6. 使用MQ的条件
- 生产者不需要从消费者处获得反馈。引入消息队列之前的直接调用,其接口的返回值应该为空,这才让明明下层的动作还没做,上层却当成动作做完了继续往后走,即所谓异步成为了可能。
- 容许短暂的不一致性。
- 确实是用了有效果。即解耦、提速、削峰这些方面的收益,超过加入MQ,管理MQ这些成本。
7. 适合的业务场景
7.1 解耦
解耦(应用之间不再直接相互访问,而是直接与消息对列对接)
7.2 异步
异步(分解一个费时的操作,把它变成多个异步执行的步骤)
7.4 削峰填谷
削峰填谷(让处理程序相对均衡地处理数据)
7.5 不适用
- 代码繁琐
- 复用性
- 立马反馈
8. 核心组件
8.1 Broker(中间件)
Broker 简单理解就是RabbitMQ服务器。接受客户端的连接,实现AMQP实体服务。