RabbitMQ架构

作者&投稿:素侍 (若有异议请与网页底部的电邮联系)
~ RabbitMQ是一个分布式系统

一、使用rabbitmq时的系统架构图

通过路由键将交换机和队列进行绑定,从而实现消息的发送和接收。

二、rabbitmq基本概念

rabbitmq是AMQP协议的一个开源实现,所以其内部实际上也是AMQP中的基本概念,如下图所示:

1、Message(消息)

消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(传输模式,指出该消息可能需要持久化存储)等。

2、Publisher

消息生产者,也是一个向交换器发布消息的客户端应用程序,就是投递消息的程序。

3、Exchange

交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。消息交换机,它指定消息按什么规则,路由到哪个队列。

4、Routing Key

路由关键字,exchange根据这个关键字进行消息投递。

5、Binding(绑定)

用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。

它的作用就是把exchange和queue按照路由规则绑定起来。

绑定其实就是关联了exchange和queue,或者这么说:queue对exchange的内容感兴趣,exchange要把它的Message deliver到queue。

6、Queue(消息队列)

消息的载体,每个消息都会被投到一个或多个队列,等待消费者连接到这个队列将其取走。它是消息的容器,也是消息的终点。

7、Connection

网络连接,例如一个TCP连接。

8、Channel(信道,通道)

消息通道,在客户端的每个连接里,可建立多个channel。

多路复用连接中的一条独立双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁TCP都是非常昂贵的开销,所以引入了信道的概念以达到复用一条TCP连接的目的。

9、Consumer

消息消费者,表示一个从消息队列中取得消息的客户端应用程序,就是接受消息的程序。

10、Virtual Host

虚拟主机,表示一批交换器、消息队列和相关对象。一个broker里可以有多个vhost,用作不同用户的权限分离。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个vhost本质上就是一个mini版的rabbitmq服务器,拥有自己的队列、交换器、绑定和权限机制。

vhost是AMQP概念的基础,必须在连接时指定,rabbitmq默认的vhost是 / 。

11、Broker

表示消息队列服务器实体。它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输。

三、AMQP中的消息路由

生产者把消息发布到Exchange上,消息最终到达队列并被消费者接收,而Binding决定交换器的消息应该发送到那个队列。如下图所示:

四、Exchange类型

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

1、direct类型

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

Driect exchange的路由算法非常简单:通过bindingkey的完全匹配,可以用下图来说明:

Exchange和两个队列绑定在一起,Q1的bindingkey是orange,Q2的binding key是black和green。

当Producer publish key是orange时,exchange会把它放到Q1上,如果是black或green就会到Q2上,其余的Message被丢弃。

2、fanout类型

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

3、topic类型

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

对于Message的routing_key是有限制的,不能是任意的。格式是以点号“.”分割的字符表。比如:”stock.usd.nyse”,“nyse.vmw”, “quick.orange.rabbit”。你可以放任意的key在routing_key中,当然最长不能超过255 bytes。对于routing_key,有两个特殊字符#和*,#匹配0个或多个单词,*只能匹配一个单词。如下图所示:

Producer发送消息时需要设置routing_key,routing_key包含三个单词和两个点号,第一个key描述了celerity(灵巧),第二个是color(色彩),第三个是物种。

在这里我们创建了两个绑定: Q1 的binding key 是”.orange.“; Q2 是 “..rabbit” 和 “lazy.#”:Q1感兴趣所有orange颜色的动物;Q2感兴趣所有rabbits和所有的lazy的。

例如:rounting_key 为 “quick.orange.rabbit”将会发送到Q1和Q2中。rounting_key 为”lazy.orange.rabbit.hujj.ddd”会被投递到Q2中,#匹配0个或多个单词。

五、ConnectionFactory、Connection、Channel

ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。

1、Connection

Connection是Rabbitmq的socket连接,它封装了socket协议相关部分逻辑。

2、ConnectionFactory

ConnectionFactory是connection的制造工厂。

3、Channel

Channel是我们与rabbitmq打交道的最重要的一个接口,大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

六、任务分发机制

1、Round-robin dispathching 循环分发

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

2、Message acknowledgment 消息确认

为了保证数据不被丢失,RabbitMQ支持消息确认机制,为了保证数据能被正确处理而不仅仅是被Consumer收到,这就需要在处理完数据之后发送一个确认ack。

在处理完数据之后发送ack,就是告诉RabbitMQ数据已经被接收并且处理完成,RabbitMQ可以将消息从队列中移除了。如果Consumer退出了但是没有发送ack,那么RabbitMQ就会把这个Message发送到下一个Consumer,这样就保证在Consumer异常退出情况下数据也不会丢失。

RabbitMQ没有用到超时机制,它仅仅通过Consumer的连接中断来确认该Message并没有被正确处理,一个消费者处理消息的时间再长也不会导致该消息被发送给其他消费者,即RabbitMQ给了Consumer足够长的时间来做数据处理。如果忘记ack,那么当Consumer退出时,Mesage会被重新分发,从而导致队列中的累积的消息越来越多,然后RabbitMQ会占用越来越多的内存。

3、Message durability 消息持久化

如果我们希望即使在rabbitmq服务重启的情况下,也不会丢失消息,我们可以将Queue与Message都设置成可持久化的(durable),这样就可以保证绝大部分情况下我们的rabbitmq消息不会丢失。但依然解决不了小概率丢失事件的发生(例如rabbitmq服务器已经接收到了生产者的消息,但还没来得及持久化该消息时rabbitmq服务器就断电了)。如果也要将这种小概率事件管理起来就需要使用到事务了。要持久化队列需要在声明时指定durable=True;这里要注意,队列的名字一定要是Broker中不存在的,不然不能改变此队列的任何属性。队列和交换机有一个创建时候指定的标志durable,durable的唯一含义就是让具有这个标志的队列和交换机会在重启之后重新建立。

消息持久化包括3部分

(1)exchange持久化,在声明时指定durable => true

channel.ExchangeDeclare(ExchangeName,"direct", durable:true, autoDelete:false, arguments:null);//声明消息队列,且为可持久的

(2)queue持久化,在声明时指定durable => true

channel.QueueDeclare(QueueName, durable:true, exclusive:false, autoDelete:false, arguments:null);//声明消息队列,且为可持久的

(3)消息持久化,在投递时指定delivery_mode => 2(1是非持久化)。

channel.basicPublish("", queueName, MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());

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

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

4、Fair dispath 公平分发

你可能也注意到了,分发机制不是那么优雅,默认状态下,RabbitMQ将第n个Message分发给第n个Consumer。n是取余后的,它不管Consumer是否还有unacked Message,只是按照这个默认的机制进行分发。那么如果有个Consumer工作比较重,那么就会导致有的Consumer基本没事可做,有的Consumer却毫无休息的机会,那么Rabbit是如何处理这种问题呢?

通过basic.qos方法设置prefetch_count=1,如下设置

channel.basic_qos(prefetch_count=1)

这样RabbitMQ就会使得每个Consumer在同一个时间点最多处理一个Message,换句话说,在接收到该Consumer的ack前,它不会将新的Message分发给它。但是这种方法可能会导致queue满。当然,这种情况下你可能需要添加更多的Consumer,或者创建更多的virtualHost来细化你的设计。

5、分发到多个Consumer

Direct Exchange:直接匹配,通过Exchange名称+RountingKey来发送与接收消息。

Fanout Exchange:广播订阅,向所有的消费者发布消息,但是只有消费者将队列绑定到该路由器才能收到消息,忽略Routing Key。

Topic Exchange:主题匹配订阅,这里的主题指的是RoutingKey,RoutingKey可以采用通配符,如:*或#,RoutingKey命名采用英文句点来分隔多个词,只有消息将队列绑定到该路由器且指定RoutingKey符合匹配规则时才能收到消息。

Headers Exchange:消息头订阅,消息发布前为消息定义一个或多个键值对的消息头,然后消费者接收消息,同时需要定义类似的键值对请求头(如

x-mactch=all或者x_match=any),只有请求头与消息头匹配,才能接收消息,忽略RoutingKey。

默认的exchange:如果用空字符串去声明一个exchange,那么系统就会使用”amq.direct”这个exchange。我们创建一个queue时,默认的都会有一个和新建queue同名的routingKey绑定到这个默认的exchange上去。如下:

channel.BasicPublish("","TaskQueue", properties, bytes);

因为在第一个参数选择了默认的exchange,而我们声明的队列叫TaskQueue,所以默认的,它要新建一个也叫TaskQueue的routingKey,并绑定在默认的exchange上,导致了我们可以在第二个参数routingKey中写TaskQueue,这样它就会找到定义的同名的queue并把消息放进去。

如果有两个接收程序都是用了同一个的queue和相同的routingKey去绑定direct exchange的话,分发的行为是负载均衡的,也就是说第一个是程序1收到,第二个是程序2收到,以此类推。

如果有两个接收程序用了各自的queue,但使用相同的routingKey去绑定direct exchange的话,分发的行为是复制的,即每个程序都会收到这个消息的副本。行为相当于fanout类型的exchange。

多个queue绑定同一个key也是可以的,对于下图的例子,Q1和Q2都绑定了black,对于routing key是black的Message,会被deliver到Q1和Q2,其余的Message都会被丢弃。

七、RPC远程过程调用

MQ本身是基于异步的消息处理,前面的示例中所有的生产者(P)将消息发送到RabbitMQ后不会知道消费者(C)处理成功或者失败(甚至连有没有消费者来处理这条消息都不知道)。 但实际的应用场景中,我们很可能需要一些同步处理,需要同步等待服务端将我的消息处理完成后再进行下一步处理。这相当于RPC(Remote Procedure Call,远程过程调用)。在RabbitMQ中也支持RPC。

RabbitMQ中实现RPC的机制如下图所示:

客户端发送请求(消息)时,在消息的属性(MessageProperties ,在AMQP 协议中定义了14种properties ,这些属性会随着消息一起发送)中设置两个值replyTo (一个Queue 名称,用于告诉服务器处理完成后将通知我的消息发送到这个Queue 中)和correlationId (此次请求的标识号,服务器处理完成后需要将此属性返还,客户端将根据这个id了解哪条请求被成功执行或执行失败)。

服务器端收到消息并处理,服务器端处理完消息后,将生成一条应答消息到replyTo 指定的Queue中 ,同时带上correlationId 属性,客户端之前已订阅replyTo 指定的Queue ,从中收到服务器的应答消息后,根据其中的correlationId 属性分析哪条请求被执行了,然后根据执行结果进行后续业务处理。

转发:https://www.cnblogs.com/jasonboren/p/13280745.html


rabbitmq 最多能多少个queue
没有限制,有限制也是取决于你的服务器性能,一般数千个乃至数万个都不是问题,当然如果真是数万个队列,那估计也是项目架构不合理了

OpenStack详细资料大全
你可以使用OpenSSL来进行MySQL 和RabbitMQ处理。(我个人还没进行测试,因此配置可能有点难。) 下一步,记住如果支持Web管理控制台,默认不适用SSL。 服务中心 中国OpenStack服务中心 概述 2013年6月18日在南京召开了“中国云计算产业促进大会暨中国OpenStack服务中心发布会”,华胜天成在会上正式宣布推出中国首家Open...

请用白话讲解ActiveMQ的用途
用途就是用来处理消息,也就是处理JMS的。消息队列在大型电子商务类网站,如京东、淘宝、去哪儿等网站有着深入的应用,队列的主要作用是消除高并发访问高峰,加快网站的响应速度。在不使用消息队列的情况下,用户的请求数据直接写入数据库,高发的情况下,会对数据库造成巨大的压力,同时也使得系统响应延迟...

云计算需要学习哪些内容?未来的发展前景怎么样呢?
第四阶段是数据库运维管理的学习,企业级项目实战:MySQL Galera高可用集群环境部署、异步消息队列集群RabbitMQ部署与运维。第五阶段的培训内容为企业级云架构管理与综合实战(PaaS+TaaS),项目训练的是基于LAMP架构实现云计算PaaS平台典型应用部署与运维,通过Nginx实现千万级并发访问处理。linux未来的发展前景:...

自学Java如何入门?
中间件板块是大型互联网项目中必备的。服务中间件可以帮助各子模块间实现互相访问,消息共享或统一访问等功能。其包括远程服务框架中间件,例如阿里(Apache)的RPC框架Dubbo等;消息队列中间件,例如:阿里巴巴开源分布式中间件RocketMQ、高吞吐量消息发布和流处理服务Kafka等。学习服务中间件是中级JavaEE工程师...

想做java开发,都要学什么?
2.基于SpringCloud完成微服务架构项目的开发 3.掌握NoSQL数据库Redis的使用 4.掌握消息队列RabbitMQ的使用 5.掌握Mycat数据库中间件的使用 知识点:1、Bootstrap前端框架、VUE前端框架、RabbitMQ消息队列。2、掌握Bootstrap前端框架开发、掌握VUE前端框架开发、掌握RabbitMQ消息队列的应用、掌握SpringBoot集成...

想要系统学习java到底要学习哪些知识
在分布式系统架构中,服务与服务之间的异步通信,是非常常见的需求之一,消息中间件的诞生正是为了解决这类问题。目前市面上的主流消息中间件有RabbitMQ、RocketMQ、Kafka,我们将学习这3个消息中间件,实现分布式项目中的异步通信。学习完这些后,可以实现分布式项目的异步通信、分布式应用日志收集、分布式事务等。 中间件板块...

Java实习工作需要具备哪些能力?
2.基于SpringCloud完成微服务架构项目的开发 3.掌握NoSQL数据库Redis的使用 4.掌握消息队列RabbitMQ的使用 5.掌握Mycat数据库中间件的使用 知识点:1、Bootstrap前端框架、VUE前端框架、RabbitMQ消息队列。2、掌握Bootstrap前端框架开发、掌握VUE前端框架开发、掌握RabbitMQ消息队列的应用、掌握SpringBoot集成...

java学习路线
如需学习Java,推荐选择【达内教育】。Java学习路线一般有以下几个阶段:第一阶段,JavaSE基础:Java环境搭建、Java流程控制语句-for循环、switch选择判断、循环嵌套、数组拷贝等。第二阶段,JavaWeb:MySQL安装、管理、创建数据库、MySQLUPDATE查询、Mysql高级操作等。第三阶段,Java高级框架-SSH:Struts2异常...

java培训要学习哪些内容?
如需java培训推荐选择【达内教育】,java培训要学习以下几点内容:1、Java基础:Java语言基础知识的学习和应用,Java使用技巧、集合框架与数据结构,数据库理论与应用、互联网网站及信息系统的开发与应用等。2、Java中级:企业团队项目协同开发与维护、商业项目模块化基础与应用、软件项目测试与实施和企业主流...

大冶市19846111357: rabbitmq和kafka的区别 -
冀雨复方: Kafka在吞吐量处理上要比RabbitMQ强很多 rabbitMQ支持miror的queue,主queue失效,miror queue接管.

大冶市19846111357: 我为什么要选择RabbitMQ -
冀雨复方: RabbitMQMQ在云计算的地位RabbitMQ大事记RabbitMQ卖点健壮易于2113使用高性能强大开源社区支持AMQP工作组成员,目前支持AMQP0-9-1RabbitMQ生态圈显微镜看RabbitMQ为什么5261要用Erlang实现Erlang消息机制与AMQP极度吻合高并发4102时间检验的高可1653靠高性能集群易扩展强大的管理功能方便的问题定位支持 AMQP交互图实现足够简单清晰高并发的秘密处处维稳自我保护AMQP协议级版别流控ErlangVM层面内存、 CPU过载防护集群层面容灾预先警报性能(单Q)性能(8个Q)集群(逻辑视图)集群(物理布局)高可用集群无中心点.权

大冶市19846111357: win 7 rabbitmq 需要安装哪些
冀雨复方: 安装 1、Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装RabbitMQ之前要先安装Erlang. 注意: 1.现在先别装最新的 3.6.3 ,本人在安装完最新的版本,queue 队列有问题,降到了 3.6.2 就解决了. 2.默认安装的Rabbit MQ 监听端口是...

大冶市19846111357: rabbitmq 控制界面怎么用 -
冀雨复方: rabbitmq 编辑 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们.消 息传递指的是程序之间通过在消息中发送数据进行通...

大冶市19846111357: 怎么在Ubuntu linux系统上安装和使用RabbitMQ -
冀雨复方: 首先保证软件包正确,然后解压后依次按下面步骤执行: 打开一个终端,su -成root用户 1>su root 正确切换到root用户,然后进入软件包解压路径 2>cd 软件解压包路径 执行软件解压包路径里的软件安装脚本 3> ./安装脚本

大冶市19846111357: 有在实际开发中用到过rabbitmq等其他消息队列的仁兄呀,最近学习了rabbitmq的各种用法, -
冀雨复方: 消息队列的作用:数据分发,缓存数据,一份数据拷贝出N份供别人使用. 适用场景:常用于一个生产者多个消费者的场景. 也可以是多个消费者一个生产者.意义:说白了就是产生数据的和消费数据的解耦合.就像是个大鱼塘,放鱼的不用管抓鱼的.抓鱼的也不用管放鱼的.你的问题: 这种场景通常因业务而产生 这说明你看的知识课本,或者简单的例子. 如果上面的说明还是没有说清楚,那么只能说明你查阅的资料还不够,或者没有专门查他的应用场景.

大冶市19846111357: rabbitmq需要开哪些端口 -
冀雨复方: 假设读者在Windows系列的操作系统中安装好了Rabbit MQ后,请找到安装路径下的etc文件夹下,将rabbitmq.config.example备份一份,并修改为config类型的文件,即为rabbitmq.config,然后,打开rabbitmq.config,找到tcp_listeners这个key,...

大冶市19846111357: springcloud 怎么利用rabbitmq -
冀雨复方:RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗.消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然.

大冶市19846111357: java 怎么通过rabbitmq 实现多channel -
冀雨复方: 展开全部1; version> org.springframework.amqp:pom文件需要加入spring集成rabbitMq的依赖,都测试通过本文代码样例都是在spring集成环境下写的.6;groupId> spring-rabbit

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网