搞懂RabbitMq,涉及消息队列、生产者、消费者、Broker、交换器、死信队列、延迟队列、TTL、工作模式、交换器类型、高可用模式

易混淆知识

工作模式:简单队列、work 模式、发布/订阅模式、路由模式、主题模式

交换机类型:fanout、direct、topic、header

高可用模式:单机模式、普通集群模式、镜像集群模式

一、RabbitMq介绍

它最初起源于金融系统,用于在分布式系统中存储转发消息。

灵活的路由: 在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能,RabbitMQ 己经提供了一些内置的交换器来实现。针对更复杂的路由功能,可以将多个交换器绑定在一起,也可以通过插件机制来实现自己的交换器。

  • 扩展性: 多个RabbitMQ节点可以组成一个集群,也可以根据实际业务情况动态地扩展集群中节点。
  • 支持多种协议: RabbitMQ 除了原生支持 AMQP 协议,还支持 STOMP、MQTT 等多种消息中间件协议。
  • 多语言客户端: RabbitMQ几乎支持所有常用语言,比如 Java、Python、Ruby、PHP、C#、JavaScript等。

二、RabbitMq中的组成

2.1 Producer(生产者) 和 Consumer(消费者)

  • Producer(生产者) :生产消息的一方(邮件投递者)
  • Consumer(消费者) :消费消息的一方(邮件收件人)

消息一般由 2 部分组成:消息头(或者说是标签 Label)和 消息体。

消息体也可以称为 payLoad ,消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括 routing-key(路由匹配规则)、priority(处理优先级)、delivery-mode(是否需要持久性存储)等。生产者把消息交由 RabbitMQ 后,RabbitMQ 会根据消息头把消息发送给感兴趣的 Consumer(消费者)。

2.2 Exchange(交换器)

总流程:消息并不是直接被投递到 Queue(消息队列) 中的,中间还必须经过 Exchange(交换器) 这一层,Exchange(交换器) 会把我们的消息分配到对应的 Queue(消息队列) 中。

两个Key:消息发送给路由时,指定路由规则RoutingKey将Exchange(交换机)与Queue(消息队列)通过BindingKey关联起来,。

匹配规则:生产者将消息发送给交换器时,需要一个RoutingKey,当 BindingKey 和 RoutingKey 相匹配时,消息会被路由到对应的队列中。

特殊情况:BindingKey 并不是在所有的情况下都生效,它依赖于交换器类型,比如fanout类型的交换器就会无视,而是将消息路由到所有绑定到该交换器的队列中。

2.3 Queue(消息队列)

Queue(消息队列) 用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

RabbitMQ 中消息只能存储在 队列 中,这一点和 Kafka 这种消息中间件相反。Kafka 将消息存储在 topic(主题) 这个逻辑层面。

2.4 Broker(消息中间件的服务节点)

一个 RabbitMQ Broker 可以简单地看作一个 RabbitMQ 服务节点,或者RabbitMQ服务实例。Broker保存着队列跟交换机。

2.5 Exchange Types(交换器类型)

RabbitMQ 常用的 Exchange Type 有 fanout、direct、topic、headers 这四种

① fanout(简单、广播)

fanout 类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中,不需要做任何判断操作,所以 fanout 类型是所有的交换机类型里面速度最快的。fanout 类型常用来广播消息。

② direct(简单、完全匹配、优先级)

direct 类型的Exchange路由规则也很简单,它会把消息路由到那些 Bindingkey 与 RoutingKey 完全匹配的 Queue 中。

direct 类型常用在处理有优先级的任务,根据任务的优先级把消息发送到对应的队列,这样可以指派更多的资源去处理高优先级的队列。

③ topic(模糊匹配、实际业务)

RoutingKey 为一个点号“.”分隔的字符串(被点号“.”分隔开的每一段独立的字符串称为一个单词),如 “com.rabbitmq.client”、“java.util.concurrent”、“com.hidden.client”;

  • BindingKey 和 RoutingKey 一样也是点号“.”分隔的字符串;
  • BindingKey 中可以存在两种特殊字符串“*”和“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)。

④ header(不实用)

三、问答

RabbitMQ 是什么?

(消息队列是什么?消息队列就是一个使用队列来通信的组件。)

RabbitMQ 是一个在 AMQP(Advanced Message Queuing Protocol )基础上实现的,可复用的企业消息系统。它可以用于大型软件系统各个模块之间的高效通信,支持高并发,支持可扩展。适合于企业级的开发。它同时实现了一个Broker构架,这意味着消息在发送给客户端时先在中心队列排队,对路由(Routing)、负载均衡(Load balance)或者数据持久化都有很好的支持。

RabbitMq的特点?

可靠性:使用持久化、传输确认及发布确认保证可靠性。

灵活的路由:在消息进入队列之前,通过交换机处理路由消息,针对复杂的路由规则,有BingingKey和RoutingKey进行匹配约束。

扩展性:根据实际业务需求,动态扩展节点成集群。

高可用性:队列在集群机器中设置镜像,保证宕机情况仍然可用。

多协议:除了原始AMQP,还支持MQTT、STOMP等消息中间件协议。

多语言:java、Python、ruby、php、js、C#

管理界面友好:用户界面易用,使得用户可以监控和管理消息跟集群中的节点。

插件:易扩展多个插件。

AMQP 是什么?

即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。

RabbitMQ 中的交换器、交换器类型、队列、绑定、路由键等都是遵循的 AMQP 协议中相 应的概念。

三层结构:

最底层:二进制数据流传输、提供帧处理。

中间层:发送客户端命令给服务器,再应答。提供可靠的同步机制和错误处理。

最高层:定义客户端调用命令,实现业务逻辑。

生产者 Producer 和消费者 Consumer?

消费者:接受信息,连接服务器,订阅队列。消费信息只是消费消息体。

生产者:发送信息,包含消息体跟标签。

Broker 服务节点、Queue 队列、Exchange 交换器?

Broker:RabbitMQ 的服务节点,一个 Broker 可以看做一个 RabbitMQ 服务器。

Queue :RabbitMQ 的内部对象,用于存储消息。多个消费者可以订阅同一队列,这时队列中的消息会被平摊(轮询)给多个消费者进行处理。

Exchange : 生产者将消息发送到交换器,由交换器将消息路由到一个或者多个队列中。当路由不到时,或返回给生产者或直接丢弃。

死信队列?如何导致的?

当消息在一个队列中变成死信 (dead message) 之后,它能被重新被发送到另一个交换器中

导致的死信的几种原因:

  • 消息被拒
  • 消息TTL(time to live)过期。
  • 队列满了,无法再添加。

什么是延迟队列?RabbitMQ 怎么实现延迟队列?

延迟队列指的是存储对应的延迟消息,消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

应用:淘宝七天自动确认收货、签收商品后,物流系统会在七天之后延时发送信息到支付系统,通知可以打款给商家了。

AMQP 协议以及RabbitMQ本身没有直接支持延迟队列的功能要实现延迟消息,一般有两种方式:

  1. 模拟:通过RabbitMQ本身队列的特性来实现,需要使用RabbitMQ的死信交换机(Exchange)和消息的存活时间TTL(Time To Live)。
  2. 3.6.x之后,可以通过插件来实现延迟队列功能。

什么是优先级队列?

优先级队列实现,优先级高的队列会先被消费

可以通过 x-max-priority参数来实现优先级队列。当消费速度小于生产速度且 Broker 有堆积的情况下,优先级才有意义。

RabbitMQ 有哪些工作模式?

  • 简单模式

  • work 工作模式

  • pub/sub 发布订阅模式

  • Routing 路由模式

  • Topic 主题模式

如何保证 RabbitMQ 的顺序?

拆分成多个队列,每个消费者单独一个队列,麻烦一点。

一个队列一个消费者,但是这个消费者内部用内存队列做排队,分发给底层不同的函数处理。

保证 RabbitMQ 高可用的?

Rabbit是基于主从(非分布式)实现的高可用,比较有代表性。

单机模式

普通集群模式:让集群中多个节点服务某个queue,多台机器上启动多个 RabbitMQ 实例,每个机器启动一个。你创建的 queue,只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据可以认为是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。

镜像集群模式:RabbitMQ 一个 queue 的数据都是放在一个节点里的,镜像集群下,也是每个节点都放这个 queue 的完整数据。性能开销太大了,消息需要同步到所有机器上,导致网络带宽压力和消耗很重

如何解决消息挤压问题?

临时紧急扩容:临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据。等快速消费完积压数据之后,得恢复原先部署的架构,重新用原先的 consumer 机器来消费消息。

如何解决消息队列的延时以及过期失效问题?

设置过期时间的,也就是 TTL。如果消息在 queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉,这个数据就没了。

批量重导:假设 1 万个订单积压在 mq 里面,没有处理,其中 1000 个订单都丢了,你只能手动写程序把那 1000 个订单给查出来,手动发到 mq 里去再补一次。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值