rabbitmq几种工作模式分别是什么?

1、work queues模式:这种模式和hello world模式不多,只不过是多个消费端,主要是应对消息太多,处理不过来的情况。多个消费端可以共同消费一个队列中的消息,他们的关系是竞争关系。

rabbitmq的几种模式(rabbitmq主题模式)rabbitmq的几种模式(rabbitmq主题模式)


rabbitmq的几种模式(rabbitmq主题模式)


2、发布模式:与work queues模式相比,此模式又多了一个角色。Exchange:交换机,每个消费者自己的队列,生产者将消息发给 broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收 到消息,此方法也成为交换机的广播类型。

3、Routing 路由模式:路由模式和上面的发布模式不太一样,应该说数据的传输更加严格,一个交换机绑定多个队列,每一个队列有route key,在绑定是key也需要绑定,发送消息时,也要指定将此消息发送到route key。

4、Topics 通配符模式:主要是一个生产者只能跟一个队列对应,Topics 通配符模式跟上面的不同是,可以通过通配符的方式,指定这个exchange中的消息由队列消费。

5、通配符模式:Topic 需要设置类型为 topic 的交换机,交换机和队列进行绑定,并且指定通配符方式的 routing key,生产者生产消息,交换机通过 routing key及其通配符,发送到对应的队列中,然后消费消息。

RabbitMQ - 介绍

各组件解释如下:

AMQP 消息的路由中增加了 Exchange 和 Binding 的角色。生产者把消息发布到 Exchange 上,消息终到达队列并被消费者接收,而 Binding 决定交换器的消息应该发送到那个队列。

Exchange分发消息时根据类型的不同分发策略有区别,目前共四种类型:direct、fanout、topic、headers 。headers 匹配 AMQP 消息的 header 而不是路由键,此外 headers 交换器和 direct 交换器完全一致,但性能很多,目前几乎用不到了,所以直接看另外三种类型:

消息中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器就将消息发到对应的队列中。路由键与队列名完全匹配,如果一个队列绑定到交换机要求路由键为"dog",则只转发 routing key 标记为"dog"的消息,不会转发"dog.puppy",也不会转发"dog.guard"等等。它是完全匹配、单播的模式。

每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。fanout 交换器不处理路由键,只是简单的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份的消息。fanout 类型转发消息是快的。

topic 交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号"#"和符号" "。

"#"匹配0个或多个单词," "匹配不多不少一个单词。

RabbbitMQ 的分发机制非常适合扩展,而且它是专门为并发程序设计的,如果现在 load 加重,那么只需要创建更多的 Consumer 来进行任务处理。

在实际应用中,可能会发生消费者收到 Queue 中的消息,但没有处理完成就宕机(或出现其他意外)的情况,这种情况下就可能会导致消息丢失。为了避免这种情况发生,我们可以要求消费者在消费完消息后发送一个回执给 RabbitMQ,RabbitMQ 收到消息回执(Message acknowledgment)后才将该消息从 Queue 中移除;如果 RabbitMQ 没有收到回执并检测到消费者的 RabbitMQ 连接断开,则 RabbitMQ 会将该消息发送给其他消费者(如果存在多个消费者)进行处理。这里不存在 timeout 概念,一个消费者处理消息时间再长也不会导致该消息被发送给其他消费者,除非它的 RabbitMQ 连接断开。 这里会产生另外一个问题,如果我们的开发人员在处理完业务逻辑后,忘记发送回执给 RabbitMQ,这将会导致的 bug——Queue 中堆积的消息会越来越多;消费者重启后会重复消费这些消息并重复执行业务逻辑。

另外 pub message 是没有 ack 的。

如果我们希望即使在 RabbitMQ 服务重启的情况下,也不会丢失消息,我们可以将 Queue 与 Message 都设置为可持久化的(durable),这样可以保证绝大部分情况下我们的 RabbitMQ 消息不会丢失。但依然解决不了小概率丢失的发生(比如 RabbitMQ 已经接收到生产者的消息,但还没来得及持久化该消息时 RabbitMQ 就断电了),如果我们需要对这种小概率也要管理起来,那么我们要用到事务。由于这里仅为 RabbitMQ 的简单介绍,所以这里将不讲解 RabbitMQ 相关的事务。

要持久化队列 queue 的持久化需要在声明时指定 durable=True;

这里要注意,队列的名字一定要是 Broker 中不存在的,不然不能改变此队列的任何属性.

队列和交换机有一个创建时候指定的标志 durable,durable 的含义就是具有这个标志的队列和交换机会在重启之后重新建立,它不表示说在队列中的消息会在重启后恢复。

消息持久化包括 3 部分

如果 exchange 和 queue 都是持久化的,那么它们之间的 binding 也是持久化的,如果 exchange 和 queue 两者之间有一个持久化,一个非持久化,则不允许建立绑定.

注意:一旦创建了队列和交换机,就不能修改其标志了,例如,创建了一个 non-durable 的队列,然后想把它改变成 durable 的,的办法就是删除这个队列然后重现创建。

你可能也注意到了,分发机制不是那么优雅,默认状态下,RabbitMQ 将第 n 个 Message 分发给第 n 个 Consumer。n 是取余后的,它不管 Consumer 是否还有 unacked Message,只是按照这个默认的机制进行分发.

那么如果有个 Consumer 工作比较重,那么就会导致有的 Consumer 基本没事可做,有的 Consumer 却毫无休息的机会,那么,Rabbit 是如何处理这种问题呢?

RabbitMQ 使用 ProtoBuf 序列化消息,它可作为 RabbitMQ 的 Message 的数据格式进行传输,由于是结构化的数据,这样就极大的方便了 Consumer 的数据高效处理,当然也可以使用 XML,与 XML 相比,ProtoBuf 有以下优势:

RabbitMQ工作模式 - 主题模式(Topic 模式) --- 2022-04-03

RabbitMQ主题模式(Topic)跟路由模式类似,区别在于主题模式的路由匹配支持通配符模糊匹配,而路由模式仅支持完全匹配。

说明:

1、P 代表生产者 , X 代表交换机,红色Q1、Q2代表队列,C1、C2 代表消费者。

2、交换机类型为topic

3、topic交换机转发消息逻辑:将消息中的Routing key与该Exchange关联的所有Binding中的Routing key进行 模糊匹配 ,如果匹配,则发送到绑定的Queue中。

topic支持的通配符如下:

如上图:

队列Q1绑定的routing key = .orange.

队列Q2绑定的routing key = ..rabbit 和 lazy.#

如果消息的routing key = “quick.orange.rabbit”, 则匹配Q1和Q2两个队列。

跟路由模式一样,区别就是条件更灵活,即Routing key的匹配规则更灵活。

RabbitMQ 进阶- 阿里云部署RabbitMQ集群

如果RabbitMQ集群只有一个broker,那么该的失效将导致整个服务临时性的不可用,并且可能会导致message的丢失(尤其是在非持久化message存储于非持久化queue中的时候)。可以将所有message都设置为持久化,并且使用持久化的queue,但是这样仍然无法避免由于缓存导致的问题:因为message在发送之后和被写入磁盘并执行fsync之间存在一个虽然短暂但是会产生问题的时间窗。通过publisher的confirm机制能够确保客户端知道哪些message已经存入磁盘,尽管如此,一般不希望遇到因单点故障导致服务不可用。

如果RabbitMQ集群是由多个broker构成的,那么从服务的整体可用性上来讲,该集群对于单点失效是有弹性的,但是同时也需要注意:尽管exchange和binding能够在单点失效问题上幸免于难,但是queue和其上持有的message却不行,这是因为queue及其内容仅仅存储于单个之上,所以一个的失效表现为其对应的queue不可用。

为了提高程序的吞吐量,保持消息的可靠性,一台机器挂了后,RabbitMQ能够正常生产,消费消息。

rabbitmq有三种模式:单机模式,普通集群模式,镜像集群模式

Demo级别的,一般只是本机测试玩玩而已,生产环境下不会用的。

在多台机器上启动多个rabbitmq实例,每个机器启动一个。

但是你创建的queue,只会放在一个rabbtimq实例上,但是每个实例都同步queue的元数据(存放含queue数据的真正实例位置)。消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从queue所在实例上拉取数据过来。

示意图

这种方式确实很麻烦,也不怎么好,没做到所谓的分布式,就是个普通集群。

普通集群的方式,确实达到了消息的高可用,但没办法保证可靠性,没做到分布式,简而言之,只是一个普通的集群。

这种模式,才是所谓的rabbitmq的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。

上图中每个有一个queue,生产者生产完毕数据后投递到指定交换机的队列,交换机的队列进行消息同步。

每个queue都有一个完整的rabbitmq,所以这种方式叫做镜像集群

好处: 任何一个宕机后,其它不受影响,正常使用

坏处:

确保机器中安装了Docker,若未安装,可看:【云原生】Docker入门 – 阿里云Linux环境下安装Docker

查看拉取的镜像

成功运行

设置1

浏览器输入 您的ip地址:15673

再次测试即可成功~

File —> New —> Project —> Men —> 直接Next 进入下一步创建普通的Men工程即可

创建一个默认的Men聚合工程,将src文件夹删除,该工程就是一个Men聚合工程

引入依赖如下:

在项目内,新建一个Moudle,rabbitmq-order-producer 默认Men工程,下一步即可

在项目内,新建一个Moudle,rabbitmq-order-cousumer 默认Men工程,下一步即可

Men聚合工程创建完成图

Men依赖图

自行手写MainApplication即可

创建完成!

编写完成!

启动消费者

交换机

=15674

15675

成功消费数据!

已成功同步消息~

Rabbitmq 使用之 Direct(默认模式)

1

Direct模式是rabbitmq的默认模式,机制大致可以理解为下图:

可以这样理解,交换机是一个车站(exChange),每个人是一个消息体(message),携带一张车票(key),在站台乘车(queue);人要乘车,于是根据票的不同,被车站分发到不同的站台,乘车去不同的地方。

即生产者发送一个指定key的消息,交换机将之转发给所有绑定此key的队列,消费者提取。

知道了流程,就考虑实现,我们订一个目标,写一个支持单发,群发的简单通讯。

show code.

2 生产者

首先创建factory

创建connection ,channel,声明一个交换机

然后发送消息(发送消息只需要建立连接,将指定key的消息发给交换机即可)

3 消费者

同样的,创建factory

创建connection ,channel,声明交换机

这里更重要的是声明队列

2、rabbitMq的高可用性方式

我们都知道MQ的稳定性至关重要,如果只是单机的应用是无法在生产环境应用。

rabbitmq在消息中间件中是比较具有代表性的,它主要基于 主从模式 进行高可用的。

rabbitmq主要有三种模式:单机、普通集群、镜像集群。

这个单机模式,就是指单应用,我们可以用来学习mq的使用,不具备生产价值。

这种模式,其实是启动了多个mq实例在不同机器上,组合成一个集群。每个实例都会同步queue的元数据(可以理解成配置信息,如exchange,queue的配置),通过元数据可以找到queue所在的实例,获取到数据。但是我们创建的queue只会放在一mq个实例上。

当然这也不是个好的模式

所以这个方案也只是比个好些,部署了多台机器,可以支撑更多的消息,提高吞吐量,但不具备高可用

镜像模式其实就是每个mq实例都有一份完整的镜像。当我们将往queue里写数据时,都会自动将消息同步到多个实例的queue中。

这种模式虽然保证了高可用,但缺点也十分明显:

【RabbitMQ-4】拉模式和推模式

我们知道,消费者有两种方式从消息中间件获取消息:

推模式: 消息中间件主动将消息 推送 给消费者

拉模式: 消费者主动从消息中间件 拉取 消息

推模式: 将消息提前推送给消费者,消费者必须设置一个 缓冲区缓存 这些消息。好处很明显,消费者总是有一堆在内存中待处理的消息,所以效率高。 缺点: 是缓冲区可能会溢出。

实现 推模式 的方式是继承 DefaultConsumer 基类,也可以使用 Spring AMQP 的 SimpleMessageListenerContainer 。

拉模式: 在消费者需要时才去消息中间件拉取消息,这段网络开销会明显 增加消息延迟,降低系统吞吐量。

实现拉模式 RabbitMQ 的 Channel 提供了 basicGet 方法用于拉取消息。

push 更关注实时性, pull 更关注消费者消费能力

推模式是做常用的,但是某些情况下推模式并不适用:

对pull的定义是:可以使用 basic.get 协议方法逐个获取消息。消息以 FIFO (先进先出)顺序获取,可以使用手动确定,就像消费者()一样。

大多数情况下,不需要逐个获取消息。因为它的效率低,并且具有轮询的所有缺点。

使用 basicGet 拉模式需要注意:

RabbitMQ支持客户端批量拉取消息,可以连续调用 basicGet 方法拉取多条消息,处理完毕一次性返回ACK。

需要注意: