一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情。
1. MQ#
MQ(Message Queue),消息队列,是生产者和消费者模型中传递信息的容器,主要用于线程或进程之间通信。
MQ主要的应用场景为:应用解耦、异步处理,流量削锋,日志处理等。
应用解耦:假设应用要与应用B、C、D通信,当某个应用挂掉或者进行调整后,其他应用都做出相应的调整。但是使用MQ之后,每个应用只需要从消息中间件中发送或消费消息,而不关心其他应用是否为正常状态。
异步处理:将消息发送到消息中间件中,继续处理下面的业务,而不需要等待消费者消费完成的响应。
流量削锋:当出现秒杀等业务场景时,短时间内将大量消息存储在消息队列中,当达到消息阈值后,消息队列拒绝接手消息,应用返回错误页面。
日志处理:业务在处理过程中,将日志使用异步方式存储,不仅不会阻塞业务执行,提高效率,而且消息中间件的可靠性也能满足业务日志不丢失等可靠性要求。
常见的MQ有:ActiveMQ、RabbitMQ、Kafka、RocketMQ、ZeroMQ,其实Redis也可以支持MQ功能。
2. 常见MQ对比#
| 特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
|---|---|---|---|---|
| 单机吞吐量 | 万级 | 万级 | 十万级 | 十万级 |
| 时效性 | ms级 | μs级 | ms级 | ms级 |
| 高可用性 | 高,主从架构 | 高,主从架构 | 非常高,分布式架构 | 非常高,分布式架构 |
| 消息可靠性 | 较低概率丢失 | 不丢失 | 优化后可不丢失 | 优化后可不丢失 |
| MQ功能支持 | 较全 | 较全 | 较全 | 简单 |
| 优点 | 功能较全 | 延时低,可靠 | 扩展性好 | 大数据领域及日志采集上普遍使用 |
3. RabbitMQ#
RabbitMQ是使用Erlang语言来编写的,并且基于AMQP协议。Erlang语言在数据交互方面性能较优秀,具有和原生Socket一样的延迟,这也是RabbitMQ高性能的原因所在。
RabbitMQ特点:
a. 开源、性能交友,消息持久化不丢失,可靠性得到保障
b. 提供可靠性的消息投递模式、返回模式
c. 与spring-boot-starter-amqp完美整合,API功能丰富且资料较多
d. 支持集群,保障高可用
4. AMQP协议#
AMQP(Advanced Message Queuing Protocol),是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端、中间件不同产品、不同开发语言等条件的限制。
AMQP基本概念:
Server:服务,接收客户端请求。
Connection:连接,应用于Server之间的TCP连接。
Channel:信道,消息的读写在信道中进行。每个客户端可以建立多个通道,每个通道即一个会话任务。
Message:消息,应用于Server之间传递的数据实体。每个消息由Properties和Body组成,Properties存储消息的优先级、延迟等配置属性,Body及消息内容。
Virtual Host:虚拟主机,用于Server内部之间逻辑隔离。每个Server之间可以有多个虚拟主机,每个虚拟主机内有多个交换机和队列,每个虚拟主机内的交换机和队列名称不能相同。
Exchange:交换机,用于接收消息,并按照一定的路由规则将消息绑定到对应的队列。常见的交换机类型有:Direct、Topic、Fanout、Header等。
Queue:队列,用于保存消息并交给消费者消费消息。
Binding:绑定,交换机和队列之间的虚拟连接,每个绑定连接中包含对一个或多个路由键。
RoutingKey:路由键,生产者发生消息时会指定对应的路由键规则,交换机根据规则将消息绑定到具体的队列上,消息者通过队列消息消息。
概念中提到两个属性:Connection和Channel。既然存在Connection,又为什么需要Channel。原因是:在一个业务场景中必然存在多个线程环境操作RabbitMQ Server进行生产和消费消息,因此将会建立多个Connection,即多个TCP连接。对于操作系统而言,TCP连接的创建和销毁是十分浪费资源的,在高并发使用场景中,势必达到性能瓶颈。所以RabitMQ采用TCP连接复用方式,使用Channel建立应用与Server连接,提高效率,也便于管理。
5. 常见交换机#
- Default Exchange
默认交换机。实则为名称为空的直连交换机。特点是每个队列都会绑定到默认交换机上,且路由键与队列名称相同。例如:创建名称为“simple-queue”的队列,AMQP代理会自动将该队列绑定到默认交换机上,绑定的路由键也为“simple-queue”。 - Direct Exchange
直流交换机。消息携带路由键(RoutingKey)经过该类型交换机时会绑定到规则匹配的队列中。
- Fanout Exchange
扇形交换机。交换机直接与队列绑定,及时绑定路由键也不起作用。当生产者发送消息后,消息经过该类型交换机直接绑定到与该交换机绑定的所有队列上。
- Topic Exchange
主题交换机。实则为直连交换机和扇形交换机相结合,即模糊匹配。其中规则为星号代表必须为一个单词,井号为零个或多个单词。例如:队列1的绑定键为A.*,队列2的绑定键为B.#,如果消息绑定的路由键为A.C,则队列1会收到;如果消息绑定的路由键为B.C.D,则队列2会收到。
- Header Exchange
头交换机。该类型交换机不依赖于路由键,而是由消息内容中的header属性进行匹配。
6. 消息确认#
消费者在消费消息往往会因为网络或其他原因导致异常,因此需要和队列建立确认机制才能表明该条消息已经成功消费。因此在AMQP协议中给出两种建议:
(1)自动确认模式:即消息发送给消费者后立即从队列中删除;
(2)手动确认模式:即消费者者将消息者处理后给队列发送确认回执(ACK机制,Acknowledgement),再根据情况删除消息。