RabbitMQ(AMQP)之一键钟情(一)
引言
关于RabbitMQ这里应有尽有,你可以了解到RabbitMQ的架构组成,四种路由、五种工作模式、应答机制、重试机制、延时队列的构建、以及消息丢失、消息积压、消息重复消费、保证消息顺序等一系列RabbitMQ相关问题的解决方案🎉🎉🎉各位少侠觉得有用一箭三连哦🤞
1 RabbitMQ架构
- Broker:接收和分发消息的应用,RabbitMQ Server就是Message Broker
- Connection: publisher / consumer和 broker之间的TCP连接
- Channel:如果每一次访问RabbitMQ都建立一个Connection,在消息量大的时候建立TCPConnection的开销将是巨大的,效率也较低。Channel是在connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯,AMQP method包含了channel id 帮助客户端和message broker识别 channel,所以channel 之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建TCP connection的开销
- Exchange: message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到queue 中去。常用的类型有: direct (point-to-point), topic(publish-subscribe) and fanout(multicast)
- **Routing Key:**生产者将消息发送到交换机时会携带一个key,来指定路由规则
- binding Key:在绑定Exchange和Queue时,会指定一个BindingKey,生产者发送消息携带的RoutingKey会和bindingKey对比,若一致就将消息分发至这个队列
- vHost 虚拟主机:每一个RabbitMQ服务器可以开设多个虚拟主机每一个vhost本质上是一个mini版的RabbitMQ服务器,拥有自己的 “交换机exchange、绑定Binding、队列Queue”,更重要的是每一个vhost拥有独立的权限机制,这样就能安全地使用一个RabbitMQ服务器来服务多个应用程序,其中每个vhost服务一个应用程序。
2 为什么用RabbitMQ
RabbitMQ 是一个开源的消息代理软件,广泛应用于构建可靠、弹性和可扩展的分布式系统。使用 RabbitMQ 有以下几个主要优势:
- 异步通信:RabbitMQ 使用消息队列的方式实现异步通信,提供了一种解耦的方式来处理不同组件之间的通信。通过将消息发送到队列中,发送者和接收者可以独立于彼此进行工作,不需要立即相互通信。
- 高度可靠:RabbitMQ 提供了持久化消息的机制,可以确保即使在发生故障时消息不会丢失。消息可以被持久化到磁盘上,并且在发生故障后可以重新发送。
- 可扩展性:RabbitMQ 支持在多个节点之间进行消息的传递和负载平衡。通过添加更多的节点,可以轻松地扩展系统的处理能力。
- 灵活的消息路由:RabbitMQ 提供了灵活的消息路由机制,可以根据消息的内容和属性将消息发送到不同的队列。这样可以更好地控制消息的流向和处理逻辑。
- 多语言支持:RabbitMQ 提供了多种客户端库,支持多种编程语言,如Java、Python、Ruby和.NET等。这使得开发者可以使用自己熟悉的语言来与消息代理进行通信。
3 RabbitMQ的四种路由
-
直连路由(Direct)
匹配路由键,只有完全匹配消息才会被转发
-
扇形广播路由(Fanout)
将消息发送至所有的队列
-
主题路由(Topic)
将路由按模式匹配,此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号"星号"匹配至多一个词。因此“abc.#”能够匹配到“abc.def.ghi”,但
是“abc.*” 只会匹配到“abc.def”。
-
消息头路由(Headers)
在绑定Exchange和Queue的时候指定一组键值对,header为键,根据请求消息中携带的header进行路由
4 🌟RabbitMQ的五种工作模式
1 simple (简单模式)
一个消费者消费一个生产者生产的信息
2 Work queues(工作模式)
一个生产者生产信息,多个消费者进行消费,但是一条消息只能消费一次
3.Publish/Subscribe(发布订阅模式)
生产者首先投递消息到交换机,订阅了这个交换机的队列就会收到生产者投递的消息
4.Routing路由模式)
生产者生产消息投递到direct交换机中,扇出交换机会根据消息携带的routing Key匹配相应的队列
5.Topics主题模式)
生产者生产消息投递到topic交换机中,上面是完全匹配路由键,而主题模式是模糊匹配,只要有合适规则的路由就会投递给消费者
5 RabbitMQ的应答机制
RabbitMQ的ACK(Acknowledgment)机制是指消费者收到消息后,向RabbitMQ服务器发送确认消息,告知服务器该消息已经被成功处理。ACK机制的实现可以通过以下两种方式来完成:
1 自动ACK(Automatic Acknowledgment)
- 在自动ACK模式下,一旦消息被消费者接收到,RabbitMQ会立即将该消息标记为已经传递,并且不再跟踪这条消息的状态。消费者无需手动发送确认消息,RabbitMQ会自动确认消息的传递。这种方式适用于不需要考虑消息处理成功与否的简单场景。
2 🌟手动ACK(Manual Acknowledgment)
- 在手动ACK模式下,消费者需要在成功处理消息后,显式地发送确认消息给RabbitMQ服务器。这种方式确保了消息在被消费者处理后得到确认,避免了消息丢失的风险。手动ACK机制通常用于需要确保消息可靠传递的场景,比如在消息处理过程中可能发生错误,需要处理失败的消息等情况。
手动ACK机制的步骤如下:
- 消费者从队列中获取消息。
- 消费者处理消息。
- 如果消息处理成功,发送ACK确认消息给RabbitMQ服务器。
- 如果消息处理失败,可以选择拒绝消息(Reject)或者将消息重新放回队列(Nack)。
6 🌟RabbitMQ的重试机制
1. 消息重试基本原理
RabbitMQ的消息重试机制基于以下原则:
- 消费者从队列中获取消息。
- 消费者尝试处理消息。
- 如果消息处理失败,将消息重新发送到队列,以供后续的重试。
2 设置重试次数
为了避免无限循环重试,我们通常会设置一个重试次数上限。这一上限可以通过在消息的属性中添加一个计数器来实现。每次消息处理失败时,计数器递增,当计数器达到设定的重试次数上限时,停止重试,将消息标记为失败或记录错误信息。
3 使用延迟队列(Delay Queue)
有时,我们需要实现消息在一定时间后进行重试。这时,可以使用RabbitMQ的延迟队列,或称为延迟交换机。消息不会立即重新放回原始队列,而是被发送到延迟队列,然后在一段时间后再次路由到原始队列,实现重试。
4 记录错误信息
记录错误信息对于排查问题非常关键。错误信息可以被写入日志文件、发送到监控系统或存储在专用的错误队列中,以供进一步分析和调查。
5 死信队列(Dead-Letter Queue)
如果消息达到了设定的重试次数上限,无法成功处理,可以将其标记为死信,并将其发送到一个死信队列中,以供后续处理或审查。这有助于避免无限重试的问题。
6 消息幂等性
为确保重试不引发不良影响,消息处理逻辑应该是幂等的。这意味着多次处理相同的消息应该产生相同的结果,而不会导致额外的副作用。