RabbitMQ的工作模式及其原理(一)

RabbitMQ的工作模式及其原理

实战例子

       实战使用:比如如何使用RabbitMQ实现订单超时未支付自动取消订单。

RabbitMQ的五大核心概念

Connection(连接),Channel(信道),Exchange(交换机)Queue(队列),Virtual host(虚拟机)。

在这里插入图片描述
Broker 译:经纪人,中间人

       图中,中间的Broker部分表示RabbitMQ服务,每个Broken里面至少有一个Virturl host 虚拟机主机,每个虚拟主机中都有自己的交换机、Queue队列以及Exchange交换机和将Queue队列之间绑定的Binding。
       Producer(生产者)和Consumer(消费者)通过·与Broker建立Connection来保持连接,然后Connection的基础上建立若干Channel信道,用来发送与接收消息。

Connection(连接)

       每个Producer(生产者)或者Consumer(消费只)要通过RabbitMQ发送与消费消息,首先就要与RabbitMQ建立连接,这个连接就是Connection。Connection是一个Tcp长连接。

Channel(信道)

       Channel是在Connection的基础上建立的虚拟连接,RabbitMQ中大部分的操作都是使用Channel完成的,比如:声明Queue,声明Exchange,发布消息,消费消息等。

Q:但是为什么已经有了Connection,为什么不完全使用Connection完成Channel的工作,为什么还要引入Channel这样一个虚拟连接的概念?
A:从系统性能的角度来说,就程序的多线程来说,如果没有Channel,每个线程在访问RabbitMQ是都要建立一个Connection这样的TCP连接,对操作系统或者服务器来收,建立和销毁TCP连接对系统或者服务器来说都是非常大的开销,在高并发,大量数据的环境下,会严重的影响系统性能。

       Channel就是为了解决这种问题,通常情况下,每个线程创建单独的Channel进行通讯,每个Channel都有自己的channel id帮助Broker和客户端识别Channel,所以Channel之间是完全隔离的。
       Connection与Channel之间的关系可以比作光纤电缆,如果把Connection比作一条光纤电缆,那么Channel就相当于是电缆中的一束光纤。

Virtual host(虚拟主机)

       Virtual host 是一个虚拟主机的概念,一个Broker中可以有多个Virtual host,每个·Virtual host都有一套自己的Exchange和QUeue,同一个Virtual host中的Exchange和Queue不能重名,不同的Virtual host中的Exchang和Queue可以一样。这样,不同的用户在访问同一个RabbitMQ Broker时,可以创建自己单独的Virtual host,然后在自己Virtual host中创建Exchange和Queue很好的做到了不同用户之间相互隔离的效果。
在这里插入图片描述

Queue(队列)

       Queue是一个用来存放消息的队列,生产者发送的消息会被放到Queue中,消费者消费消息时也是从Queue中取走消息。

Exchange(交换机)

       Exchange是一个比较重要的概念,它是消息到达RabbitMQ的第一站,主要负责根据不同的分发规则将消息分发到不同的Queue,提供了订阅相关Queue的消费者消费到指定的消息。Exchange有四种分发消息的规则:
       Direct,Fanout,Topic,Header。

       学前铺垫: RoutingKey,(路由键),当Exchange和Queue被创建好之后,需要使用Routing Key (通常叫做Binding Key)将他们绑定起来,Producer在向Exchange发送一条消息的时候,必须指定一个Routing Key ,然后Exchange接收到这条消息后,会解析Routing Key,然后根据Exchange 和 Queue的绑定规则,将消息分发到符合规则的Queue中。

在这里插入图片描述

1.DIrect

       Direct的意思是直接的,Direct类型的Exchange会将消息转发到指定Routing Key 的Queue,Routing Key 的解析规则为精确匹配。也是就只有当Producer发送消息的Routing Key与某个Bingding Key相等时,消息才会被分发到对应的Queue上。

比如我们现在有一个direct类型的Exchange,它下面绑定了三个Queue,Binding key分别是ORDER/GOODS/STOCK:
在这里插入图片描述
然后我们向该Exchange中发送一条消息,消息的Routing key是ORDER:
在这里插入图片描述
按照规则分析,这条消息应该被路由到MY_EXCHANGE_ORDER_QUEUE这个Queue。消息发送成功之后,我们去Queues中查看,发现确实只有MY_EXCHANGE_ORDER_QUEUE这个QUEUE接收到了一条消息。
在这里插入图片描述
进入这个队列,通过getMessage取出消息查看,确实是我们刚才手动发送的那条消息。
在这里插入图片描述
所以,direct类型的Exchange在分发消息时,必须保证producer发送消息的Routing key与Exchange和Queue绑定的Binding key相等才可以。

2.Fanout

       Fanout是扇形的意思,该类型通常叫作广播类型。fanout类型的Exchange不处理Routing key,而是会将发送给它的消息路由到所有与它绑定的Queue上。

在这里插入图片描述
比如我们现在有一个fanout类型的Exchange,它下面绑定了三个Queue,Binding key分别是ORDER/GOODS/STOCK:
在这里插入图片描述
然后我们向该Exchange中发送一条消息,消息的Routing key随便填一个值abc:
在这里插入图片描述
按照规则分析,这条消息应该被路由到所有与该Exchange绑定的Queue,即三个Queue都应该会受到消息。消息发送成功之后,我们去Queues中查看,发现确实每个QUEUE都接收到了一条消息。在这里插入图片描述
进入这三个QUEUE,通过getMessage取出消息查看,确实是我们刚才手动发送的那条消息。
在这里插入图片描述
所以,fanout类型的Exchange不管Routing key是什么,它都会将接收到的消息分发给所有与自己绑定了的Queue上。

Topic

       Topic的意思是主题,Topic类型的Exchange会根据通配符对Routing Key 进行匹配,只要Routing Key满足某个通配符的条件,就会被路由到对应的Queue上。通配符的匹配规则如下:

序号描述
1Routing Key必须是一串字符串,每个单词用“.”分隔
2符号“#”表示匹配一个或多个单词;
3符号“*”表示匹配一个单词。

例如:“*.123” 能够匹配到 “abc.123”,但匹配不到 “abc.def.123”;“#.123” 既能够匹配到 “abc.123”,也能匹配到 “abc.def.123”。
比如我们现在有一个topic类型的Exchange,它下面绑定了4个Queue,Binding key分别是 .ORDER、GOODS.、#.STOCK、USER.#。
在这里插入图片描述
然后我们向该Exchange中发送一条消息,消息的Routing key为:USER.ABC.ORDER。

在这里插入图片描述
按照规则分析,USER.ABC.ORDER这个Routing key只可以匹配到 “USER.#” ,所以,这条消息应该被路由到MY_TOPIC_USER_QUEUE这个Queue中。消息发送成功之后,我们去Queues中查看,发现结果符合我们的预期。
在这里插入图片描述
进入这个QUEUE,通过getMessage取出消息查看,确实是我们刚才手动发送的那条消息。

在这里插入图片描述

Headers

       日常工作中,以上三种类型的Exchange已经能够满足我们基本上所有的需求了,Headers模式并不经常使用,我们只需要对Header Exchange 有有一个基本的了解就可以了。Headers Exchange 中,Exchange与Queue之间的绑定不再通过Binding Key绑定,而是通过Arguments绑定,比如我们现在有一个Headers类型的Exchange,下面通过不同的Arguments绑定了三个Queue
在这里插入图片描述

producer在发送消息时可以添加headers属性,Exchange接收到消息后,会解析headers属性,只要我们上面配置的Arguments中的所有属性全部被包含在Headers中并且值相等,那么这条消息就会被路由到对应的Queue中。
比如我们向上面的Exchange中发送一条消息,消息的Headers中添加“x=1”:

在这里插入图片描述
根据规则,只有queue1这个队列满足x=1的条件,queue2中的y=2条件不满足,所以,消息应该只被路由到queue1队列中。消息发送成功后,我们可以看到queue1确实收到了消息:

在这里插入图片描述
并且这条消息就是我们刚才手动发送的消息:
在这里插入图片描述
然后我们再发送一条消息,消息的headers中有两个属性:x=1,y=2:
在这里插入图片描述
根据规则,queue1的x=1的条件满足,queue2的x=1、y=2的条件满足,queue3的y=2的条件满足,所以,这三个Queue应该都能够收到这条消息。消息发送成功后,结果符合预期:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值