【消息队列】RabbitMQ基本概念

举报
MoCrane 发表于 2024/08/11 12:49:54 2024/08/11
【摘要】 RabbitMQ的死信队列(Dead Letter Queue,简称DLQ)是一种用于处理消息处理失败或无法路由的消息的机制。它允许将无法被正常消费的消息重新路由到另一个队列,以便稍后进行进一步的处理、分析或排查问题。**消息处理失败:**当消费者由于代码错误、消息格式不正确、业务规则冲突等原因无法成功处理一条消息时,这条消息可以被标记为死信。**消息过期:**在RabbitMQ中,消息可以设置过

1.RabbitMQ的架构

Producer(生产者): 生产者是消息的发送方,负责将消息发布到RabbitMQ的交换器 (Exchange)。

Consumer(消费者): 消费者是消息的接收方,负责从队列中获取消息,并进行处理和消费。

Exchange(交换器): 交换器是消息的接收和路由中心,它接收来自生产者的消息,并将消息路由到一个或多个与之绑定的队列(Queue)中。

Queue(队列): 队列是消息的存储和消费地,它保存着未被消费的消息,等待消费者(Consumer) 从队列中获取并处理消息。

Binding(绑定): 绑定是交换器和队列之间的关联关系,它定义了交换器将消息路由到哪些队列中。

VHost(虚拟主机): 它类似于操作系统中的命名空间,用于将RabbitMQ的资源进行隔离和分组。每个VHost拥有自己的交换器、队列、绑定和权限设置,不同VHost之间的资源相互独立,互不干扰。VHost可以用于将不同的应用或服务进行隔离,以防止彼此之间的消息冲突和资源竞争。

2.RabbitMQ的工作模式

  1. 简单模式(Simple Mode):在这种模式下,有一个生产者和一个消费者。生产者发送消息,消费者接收并处理这些消息。这种模式是最简单的RabbitMQ使用方式。
  2. Work模式(Work Queues):在这种模式下,有一个生产者和多个消费者。生产者发送消息到队列中,消费者从队列中取出消息进行处理。RabbitMQ通过轮询的方式将消息平均发送给消费者,确保一条消息只被一个消费者接收和处理。
  3. 发布/订阅模式(Publish/Subscribe):在这种模式下,生产者发送消息到交换机,交换机将消息广播到所有与之绑定的队列中,然后消费者从队列中取出消息进行消费。这种模式允许消费者有选择性地接收消息。
  4. 路由模式(Routing):路由模式与发布/订阅模式类似,但是生产者发送消息时需要指定一个路由键(routing key),交换机根据路由键将消息发送到匹配的队列中。消费者需要将其队列绑定到交换机,并指定路由键以便接收消息。
  5. Topic模式:这种模式是路由模式的扩展,它使用更灵活的匹配规则。生产者发送消息时指定一个路由键,消费者可以将其队列绑定到交换机上,并指定一个模式(topic),该模式可以包含通配符,用于匹配路由键。这样,消费者可以接收符合特定模式的所有消息。
  6. RPC模式:支持生产者和消费者不在同一个系统中,即允许远程调用的情况。通常,消费者作为服务端,放置在远程的系统中,提供接口,生产者调用接口,并发送消息。

3.RabbitMQ的作用

  1. 应用解耦:在生产者和消费者之间建立了一个缓冲区,使得两者之间的处理速度可以异步进行,不需要严格匹配。这大大增加了系统的灵活性和可扩展性。
  2. 削峰填谷:在高并发场景下,大量请求可能瞬间涌入系统,导致系统压力过大。RabbitMQ可以作为一个缓冲存储,将一部分请求暂时存入队列中,起到“削峰”的作用,保证系统平稳运行,在高峰期过去后,继续从队列中取出消息进行处理,直到积压的消息被完全消费。
  3. 异步通信:RabbitMQ支持异步通信,生产者将消息发送到队列后,不必等待消费者处理完消息再返回结果,而是可以继续执行其他任务。这大大提高了系统的并发处理能力和响应速度。
  4. 流量整形:RabbitMQ可以对消息进行优先级排序、延迟处理等,使得消息的处理更加有序和高效。

4.如何处理RabbitMQ的消息积压问题?

  1. 增加消费者数量:当消息队列中的消息数量超出当前消费者的处理能力时,可以动态地增加消费者的数量。这样,更多的消费者可以并行地处理消息,从而加快消息的消费速度。
  2. 提高消费者的处理能力:优化消费者的代码逻辑,提升消费者的性能,例如通过多线程或其他并行处理技术,可以提高单个消费者的处理速度。
  3. 设置消息的过期时间:为了避免消息无限期地积压在队列中,可以为消息设置一个合理的过期时间。当消息在队列中等待时间过长且未被消费时,RabbitMQ可以自动将其丢弃或进行其他处理。

5.RabbitMQ的死信队列

死信队列介绍

RabbitMQ的死信队列(Dead Letter Queue,简称DLQ)是一种用于处理消息处理失败无法路由的消息的机制。它允许将无法被正常消费的消息重新路由到另一个队列,以便稍后进行进一步的处理、分析或排查问题。

当消息队列里面的消息出现以下几种情况时,就可能会被称为”死信”:

  1. 消息处理失败: 当消费者由于代码错误、消息格式不正确、业务规则冲突等原因无法成功处理一条消息时,这条消息可以被标记为死信。
  2. 消息过期: 在RabbitMQ中,消息可以设置过期时间。如果消息在规定的时间内没有被消费,它可以被认为是死信并被发送到死信队列。
  3. 消息被拒绝: 当消费者明确拒绝一条消息时,它可以被标记为死信并发送到死信队列。拒绝消息的原因可能是消息无法处理,或者消费者认为消息不符合处理条件。
  4. 消息无法路由: 当消息不能被路由到任何队列时,例如,没有匹配的绑定关系或路由键时,消息可以被发送到死信队列。

当消息变成”死信”之后,如果配置了死信队列,它将被发送到死信交换机,死信交换机将死信投递到一个队列上,这个队列就是死信队列。但是如果没有配置死信队列,那么这个消息将被丢弃。

配置死信队列

在RabbitMQ中,死信队列通常与交换机(Exchange) 和队列(Queue) 之间的绑定关系一起使用。要设置死信队列,通常需要以下步骤:

  1. 创建死信队列: 定义一个用于存储死信消息的队列。
  2. 创建死信交换机: 为死信队列定义一个交换机,通常是一个direct类型的交换机。
  3. 将队列与死信交换机绑定: 将主要队列和死信交换机绑定,以便无法处理的消息能够被转发到死信队列。
  4. 在主要队列上设置死信属性: 通过设置队列的**x-dead-letter-exchangex-dead-letter-routing-key**属性,来指定死信消息应该被发送到哪个交换机和路由键。

当消息被标记为死信时,它将被发送到死信队列,并可以由应用程序进一步处理、审查或记录。这种机制有助于增加消息处理的可靠性和容错性,确保不丢失重要的消息,并提供了一种处理失败消息的方式。

6.RabbitMQ如何实现延迟队列

死信队列

当RabbitMQ中的一条正常的消息,因为过了存活时间(TTL过期)、队列长度超限、被消费者拒绝等原因无法被
消费时,就会变成Dead Message,即死信

实现方法

当一个消息变成死信之后,他就能被重新发送到死信队列中(其实是交换机-exchange)。基于这样的机制,就可以实现延迟消息了。那就是我们给一个消息设定TTL,但是并不消费这个消息,等他过期,过期后就会进入到死信队列,然后我们再监听死信队列的消息消费就行了。

而且,RabbitMQ中的这个TTL是可以设置任意时长的,这相比于RocketMQ只支持一些固定的时长而显得更加灵活一些。

死信队列实现延迟队列的缺点

但是,死信队列的实现方式存在一个问题,那就是可能造成队头阻塞,因为队列是先进先出的,而目每次只会判断队头的消息是否过期,那么,如果队头的消息时间很长,一直都不过期,那么就会阻塞整个队列,这时候即使排在他后面的消息过期了,那么也会被一直阻塞。

基于RabbitMQ的死信队列,可以实现延迟消息,非常灵活的实现定时关单,并且借助RabbitMQ的集群扩展性可以实现高可用,以及处理大并发量。他的缺点一是可能存在消息阻塞的问题;二是方案比较复杂,不仅要依赖RabbitMQ,而且还需要声明很多队列出来,增加系统的复杂度。

RabbitMQ插件

实现方法

基于插件的方式,消息并不会立即进入队列,而是先把他们保存在一个基于Erlang开发的Mnesia数据库中,然后通过一个定时器去查询需要被投递的消息,再把他们投递到x-delayed-message交换机中。

基于RabbitMQ插件的方式可以实现延迟消息,并且不存在消息阳塞的问题,但是因为是基于插件的,而这个插件
支持的最大延长时间是(232)-1 毫秒,大约49天,超过这个时就会被立即消费。

RabbitMQ插件实现延迟队列的缺点

不过这个方案也有一定的限制,它将延迟消息存在于 Mnesia 表中,并且在当前节点上具有单个磁盘副本,存在丢失的可能。

目前该插件的当前设计并不真正适合包合大量延迟消息(例如数十万或数百万)的场景,另外该插件的一个可变性来源是依赖于 Erlang 计时器,在系统中使用了一定数量的长时间计时器之后,它们开始争用调度程序资源,并且时间漂移不断累积。

7.保证RabbitMQ的消息可靠性

为了确保消息不丢失,可以采取以下措施:

  1. 持久化消息: 将消息持久化到磁盘中,这样即使系统崩溃,消息也不会丢失。常见的MQ如RabbitMQ、Kafka、ActiveMQ都支持消息持久化。
  2. 确认机制(Acknowledgment): 发送方和接收方都需要确认消息的接收。发送方在发送消息后等待接收方的确认,接收方处理消息后需要确认已成功处理。
  3. 重复发送: 如果在设定时间内没有收到确认,发送方可以重试发送消息。这需要消息处理具备幂等性,即多次处理同一条消息不会造成副作用。
  4. 死信队列(Dead Letter Queue, DLQ): 当消息无法被成功处理或无法被确认时,将其转移到死信队列中进行后续处理。
  5. 高可用集群: 通过MQ集群来实现高可用性,防止单点故障导致消息丢失。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。