RabbitMQ的工作流程

序言

        对比Kafka会发现, RabbtiMQ提供的功能更多,在生产者与消费者的安全性上提供了更多的控制手段.同时消息队列的类型也比较多.竟然还有RPC的模式 所以在并发量不是很大的情况下,且对消息的安全(主要指消息的丢失)要求比较高的情况下可以使用Kafka.如有建议请骚扰:[email protected]

参考资料:https://www.cnblogs.com/williamjie/p/9481774.html

 https://www.cnblogs.com/wangsen/p/11057714.html

RabbitMq组成部分

整体流程图

直接用的同仁的图哈

ConnectionFactory、Connection、Channel

       ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的socket链接,它封装了socket协议相关部分逻辑。ConnectionFactory为Connection的制造工厂。
       Channel是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

        信道(即Channel)的原理是一条线程一条通道,多条线程多条通道同用一条TCP链接。一条TCP链接可以容纳无限的信道,即使每秒成千上万的请求也不会成为性能的瓶颈。

Publisher

      向交换器发布消息的客户端应用程序,即消息的生产者

Consumer 

     从消息队列中取得消息的客户端应用程序,即消息的消费者

Queue

Queue(队列)是RabbitMQ的内部对象,用于存储消息,用下图表示。
 

RabbitMQ中的消息都只能存储在Queue中,生产者(下图中的P)生产消息并最终投递到Queue中,消费者(下图中的C)可以从Queue中获取消息并消费。多个消费者可以订阅同一个Queue,这时Queue中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理。(另外需要注意的是 生产者不是跟队列直接相连的,中间还有个exchange,这里省略了)

routing key

     生产者在将消息发送给Exchange的时候,一般会指定一个routing key,来指定这个消息的路由规则,而这个routing key需要与Exchange Type及binding key联合使用才能最终生效。(Exchange type 就是 exchange的路由类型, binding key就是exchange与queue绑定时的一个key,相当于给这个绑定取个名字.这个名字是跟 routing key 相同或者包含的)

 

Binding

     RabbitMQ中通过Binding将Exchange与Queue关联起来,这样RabbitMQ就知道如何正确地将消息路由到指定的Queue了。

 

Binding key

       在绑定(Binding)Exchange与Queue的同时,一般会指定一个binding key;消费者将消息发送给Exchange时,一般会指定一个routing key;当binding key与routing key相匹配时,消息将会被路由到对应的Queue中。这个将在Exchange Types章节会列举实际的例子加以说明。
      在绑定多个Queue到同一个Exchange的时候,这些Binding允许使用相同的binding key。binding key 并不是在所有情况下都生效,它依赖于Exchange Type,比如fanout类型的Exchange就会无视binding key,而是将消息路由到所有绑定到该Exchange的Queue。

Exchange

用来接收生产者发送的消息并将这些消息路由给服务器中的队列。(根据Exchange Type来决定 怎么分发到不同的Queue上)

 

Exchange Types

RabbitMQ常用的Exchange Type有fanout、direct、topic、headers这四种(AMQP规范里还提到两种Exchange Type,分别为system与自定义,这里不予以描述),下面分别进行介绍。另模式其实还有更多,但是常用的就这几种.欢迎大家骚扰:[email protected]

1 fanout(广播模式)

fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。即每个Queue都会收到相同的消息.

下图中,生产者(P)发送到Exchange(X)的所有消息都会路由到图中的两个Queue(两者收到的消息都是一样的.),并最终被两个消费者(C1与C2)消费。

2 direct(完全匹配模式)

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

如下所示:orange,black,green是 binding key. 那在此类型下,如果消息的生产者发送了routing key为 orange的消息,则会去Q1这个队列,如果routing key为green 则会去Q2这个队列
 

3 topic(正则匹配模式)

        direct类型的Exchange路由规则是完全匹配binding key与routing key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到binding key与routing key相匹配的Queue中,但这里的匹配规则有些不同,它约定:

  • routing key为一个句点号“. ”分隔的字符串(我们将被句点号“. ”分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”
  • binding key与routing key一样也是句点号“. ”分隔的字符串
  • binding key中可以存在两种特殊字符“*”与“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)

如上可以看到,binding key 都变成了正则表达式. 这样就会模糊匹配满足条件的routing key 到指定的queue上

以上图中的配置为例,routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2,routingKey=”lazy.orange.fox”的消息会路由到Q1,routingKey=”lazy.brown.fox”的消息会路由到Q2,routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次,虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。

4 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属性分析哪条请求被执行了,根据执行结果进行后续业务处理
发布了62 篇原创文章 · 获赞 50 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/cuiyaonan2000/article/details/102818245