RabbitMQ原理及集群的深入剖析

本文深入剖析RabbitMQ的工作原理,包括其组件(如交换机、队列、绑定)及其应用场景,如订单系统、秒杀系统。讨论了Exchange的四种类型:fanout、direct、topic、headers。探讨了消息的持久化、集群模式(普通模式和镜像模式)以及与其他消息中间件的对比。文中还提供了RabbitMQ在Windows环境下的安装步骤和集群搭建过程,附带了简单的生产-消费测试代码。
摘要由CSDN通过智能技术生成

说在前面

由于公司最近项目中使用到了RabbitMQ,以前只是停留在发消息、消费消息,通过学习一些资料,今日来记录和复习下RabbitMQ的基本原理及高级应用。本文主要阐述RabbitMQ工作原理及安装过程,以及集群的搭建过程,同时与常用的消息中间件进行了比对分析,简要阐述其不同的组件在不同场景下的应用。

文末是对RabbitMQ的安装及集群搭建实操过程,希望能对你带来帮助。

RabbitMQ应用场景剖析

在说到应用场景之前,我想这几个问题你不妨先思考一番;

  1. 什么时候会用到消息中间件?
    答:“当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消息队列”
  2. 为什么要用?
    本来蛮简单的一个系统,现在凭空接入一个中间件,是不是要考虑去维护它,而且使用的过程中还要要考虑各种问题,比如消息重复消费、消息丢失、消息的顺序消费等等。
  3. 消息中间件有什么具体作用?
    复杂系统的解耦,复杂链路的异步调用,瞬时高峰的削峰处理

这三个问题你清楚了,你对RabbitMQ的上手就快了!

  1. 订单-库存系统
    在这里插入图片描述

订单系统:
用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
库存系统:
订阅下单的消息,获取下单消息,进行库操作。 就算库存系统出现故障,消息队列也能保证消息的可靠投递,不会导致消息丢失。
(此图是不是有点熟悉,没事,下面的你也挺熟悉的。)

  1. 秒杀系统
    在这里插入图片描述
    1.在服务器收到用户的请求之后,首先写入消息队列,假如消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面。
    2.秒杀业务根据消息队列中的请求信息,再做后续处理。

  2. 微信、QQ红包

在这里插入图片描述
1.用户的抢红包的请求首先写入消息队列.
2.红包业务根据消息队列中的请求信息,依次处理.

红包系统也好、库存系统也罢,相信通过枚举的这三种系统,你已经很清楚消息中间件的作用了。
到这,你也对RabbitMQ有了一个初步的认识,接下来我们来具体解刨一下RabbitMQ,它里面到底有什么!

RabbitMQ的组件剖析

在这里插入图片描述
如图所示,此图为RabbitMQ整个系统内的结构。
Producer:消息生产者,就是投递消息的程序。
Broker:它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输。
Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
Queue:消息的载体,每个消息都会被投到一个或多个队列。
Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来.
Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
vhost:虚拟主机,一个broker里可以有多个vhost,用作不同用户的权限分离。
Consumer:消息消费者,就是接受消息的程序.
Channel:消息通道,在客户端的每个连接里,可建立多个channel.

通信过程如下
1:Producer生产消息,发送给服务器端的Exchange。
2:Exchange收到消息,根据ROUTINKEY,将消息转发给匹配的Queue。
3:Queue收到消息,将消息发送给订阅者Consumer。
4:Consumer收到消息,发送ACK给队列确认收到消息。
5:Queue收到ACK,删除队列中缓存的此条消息(ACK为确认机制,后续会做介绍)。

说一说绑定过程:

在这里插入图片描述
交换机和队列之间的关系:
生产者将消息投递给交换机,然后由交换器路由到一个或多个队列中,在这里我们需要重点理解下,交换机是如何路由到对应的队列?

Bindings需要告诉exchange发送消息到队列中,exchange和queue之间的关系就叫binding。
RoutingKey和BindingKey生产者将消息发送给交换机,一般会指定一个RoutingKey,通过这个指定这个消息的路由规则,而这个RoutingKey需要与交换机的类型和Bindingkey联合使用才能生效。
RoutingKey是决定消息的流向的,生产者将消息发送给交换机时,需要一个RoutingKey,当BindingKey和RoutingKey相匹配时,消息会被路由到对应的队列中。
Exchange和两个队列绑定在一起,假设队列1的bindingkey是orange,队列2的binding key是black和green. 当生产者的RoutingKey是orange时,exchange会把它放到队列1上,如果是black或green就会到队列2上,其余的Message被丢弃.

Exchange类型

Exchange交换机的类型有fanoutdirecttopicheaders四种模式。

在这里插入图片描述

Fanout
会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中,也就是广播模式。
很容易理解,无定向,通通发出去。
Direct广播模式

Direct
交换器会把消息路由到那些BindingKey和RoutingKey完全匹配的队列中。
1:当生产者(P)发送消息时Rotuing key=booking时,这时候将消息传送给Exchange,Exchange获取到生产者发送过来消息后,会根据自身的规则进行与匹配相应的Queue,这时发现Queue1和Queue2都符合,就会将消息传送给这两个队列。
2:如果我们以Rotuing key=create和Rotuing key=confirm发送消息时,这时消息只会被推送到Queue2队列中,其他Routing Key的消息将会被丢弃。

应用场景
大规模多用户在线(MMO)游戏可以使用它来处理排行榜更新等全局事件
体育新闻网站可以用它来近乎实时地将比分更新分发给移动客户端,分发系统使用它来广播各种状态和配置更新
在这里插入图片描述

topic
其与direct类型交换机规则些许不同,topic采用模糊匹配的方式,可以通过通配符满足一部分规则就可以传送:
1:routing key为一个句点号“.”用来分隔的字符串(句点号“. ”分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”。
2:binding key与routing key一样也是句点号“. ”分隔的字符串。
binding key中可以存在两种特殊字符“*”与“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)

当生产者发送消息Routing Key=F.C.E的时候,这时候只满足Queue1,所以会被路由到Queue中,如果Routing Key=A.C.E这时候会被同是路由到Queue1和Queue2中,如果Routing Key=A.F.B时,这里只会发送一条消息到Queue2中。

应用场景:

1:例如销售点由多个工作者(workers)完成的后台任务,每个工作者负责处理某些特定的任务。
2:涉及到分类或者标签的新闻更新(例如,针对特定的运动项目或者队伍)。

一些事项

1:消息一般可以包含2个部分:消息体和标签(Label) 。消息体也可以称之为payload,在实际应用中,消息体一般是一个带有业务逻辑结构的数据,比如一个 JSON 字符串。
2:交换机匹配过程
★:Direct Routing Key=Binding Key,严格匹配
★:Fanout 把发送到该 Exchange 的消息路由到所有与它绑定的 Queue 中
★:Topic Routing Key=Binding Key,模糊匹配
★:Headers 根据发送的消息内容中的 headers 属性进行匹配
3:RabbitMQ中消息都只能存储在队列中,队列的特性是先进先出。
4:如果cosumer接受了消息, 但在发送ack之前断开连接,rabbitmq会认为这条消息没有被deliver,在consumer在次连接的时候,这条消息会被redeliver。

一些思考

1:如何确保消息正确地发送至 RabbitMQ? 如何确保消息接收方消费了消息?

发送方确认模式将信道设置成 confirm 模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一的 ID。一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送一个确认给生产者(包含消息唯一 ID)。

如果 RabbitMQ 发生内部错误从而导致消息丢失,会发送一条 nack(notacknowledged,未确认)消息。这里并没有用到超时机制,RabbitMQ 仅通过 Consumer 的连接中断来确认是否需要重新发送消息。

2:消息基于什么传输?

由于 TCP 连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。
RabbitMQ 使用信道的方式来传输数据。信道是建立在真实的 TCP 连接内的虚拟连接,且每条 TCP 连接上的信道数量没有限制。

3:消息产生者将消息放入队列消费者可以有多个消费!

消费者1,消费者2同时监听同一个队列,消息被消费。C1 C2共同争抢当前的消息队列内容,谁先拿到谁负责消费消息(隐患:高并发情况下,默认会产生某一个消息被多个消费者共同使用,可以设置一个开关(syncronize) 保证一条消息只能被一个消费者使用)。

关于持久化

1:为什么要持久化?

处理消息队列丢数据的情况,就需要开启持久化磁盘的配置,这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值