导语

本文从AMQP协定(Advanced Message Queuing Protocol,高级音讯队列协定)、音讯性能、生产模型、金融级用法及其他性能点比照等概念介绍对RabbitMQ做了科普, 心愿对各位深刻了解RabbitMQ有帮忙。

AMQP协定概念

AMQP协定本身定义了很多概念,上面先对这些概念进行分析,会更偏重从每个概念实体的作用域、职责范畴、从属关系等维度进行介绍。

Connection

  • 对应底层一个AMQP-Client到RabbitMQ-Broker的一个TCP连贯。
  • 这边要思考两个端点问题,在TCP连贯建设实现后,如下图所示,连贯的指标Broker就曾经确定是集群中的一台了,因为是长连贯,除非断连重建,否则对端节点不可变。
  • 所以从这里能够看出RabbitMQ相比Pulsar、RocketMQ不一样的中央在于,其是一种服务端寻址模型,以Client的视角来看,想要连贯任意Exchange、Queue,只有连上任意一台Broker就行。

Channel

  • 信道,能够了解为一种逻辑连贯,体现了多路复用的设计思路。
  • 反对串行执行,包含收和发的指令,能够了解为一种半双工模式的“虚构网络通道”。
  • 所有Exchange、Queue、Binding的操作都是在Channel之上进行的。

Vhost

  • 等价于一种租户隔离概念,不同Vhost下能够创立同名Exchange、Queue,这样能够进行业务隔离。
  • RabbitMQ的权限隔离和权限维度管制的机制是在Vhost级别的。
  • Rabbit官网原生的全局Policy管制在Vhost级别。

Exchange

  • 一个虚构实体,申明不同音讯的路由策略,本身不存储音讯。
  • 一个路由器,基于音讯头部的RoutingKey和Header将音讯路由到符合条件的具体的Queue。
  • 反对单播和播送。

Queue

  • 音讯存储实体,是音讯底层存储的容器,相似Pulsar的Topic。
  • 单订阅模式,其下的Consumer别离生产到一部分音讯。
  • 和存储关联,因而有容量下限、TTL等存储层的个性。
  • 反对多生产和独占生产,取决于你订阅时设置的参数。因为它是存储音讯零碎的音讯,所以外部基于一个音讯位点管制长久化生产进度,记录最初被生产并Ack的地位。
  • 面向Consumer。

Binding

  • 连接Exchange和Queue的桥梁,实质是一个规定的申明。
  • 一个Exchange下能够有多个Binding。
  • 一个Queue也能够被多个Binding关联。
  • 一个Exchange到一个Queue也能够申明多个Binding。

音讯性能

上面介绍RabbitMQ官网所提供的的开源原生性能,咱们晓得,AMQP协定能够看做成一种可编程式的音讯队列协定,能够基于其提供的根底模型,通过本人的奇妙搭配组合,结构出多种多样的业务模型。

音讯构造

# publishInfoexchange: amq.directimmediate: falsemandatory: falseroutingKey: test# headerBodybodySize: 1024properties:     - contentType:     - encoding:     - deliveryMode:     - priority:     - correlationId:     - replyTo:     - expiration:     - messageId:     - timestamp:     - type:     - userId:     - appId:     - clusterId:     - headers: {}# contentBody二进制音讯体bytes

每个音讯分为三个局部,在网络层面即三个独立数据帧:

  • PublishInfo: 音讯路由申明信息,能够联想成写电子邮件时填写的指标邮箱、是否接管回执等前置申明。
  • HeaderBody: 音讯头部,用于存储RabbitMQ本身当时定义的申明,能够联想层HTTP协定的Header一样,此处能够搁置一些对业务通明的上下文信息用于提供某种性能,比方分布式链路追踪的TraceId。
  • ContentBody: 音讯体,无差别二进制数据块,服务端不感知其是否压缩、是否加密等,只进行通明的存储和读取投递。

work queue 工作队列

  • 它是一种模型简化,发送音讯时指定Exchange为空,RoutingKey为QueueName,Broker当前会间接把这个音讯发送至指标Queue,这样对用户来说相当于没Exchange,他认为是间接用Queue来生产,就比较简单。
  • 工作队列只实用于单订阅的场景,因为Queue只实用于单订阅。
  • 官网解说

Publish/Subscribe 公布订阅模式

Queue不反对多订阅,通过转换思路实现:

  • 一个Fanout类型的Exchange:相当于多订阅场景的Topic。
  • 多个不同的Queue:绑定到该Exchange,相当于多订阅场景下的Subscription。
  • 多个Consumer生产同一个Queue:惯例场景多订阅。
  • 每个Consumer各自生产一个Queue:实例级别播送。
  • 官网解说
  • 对齐RocketMQ、Pulsar的多订阅生产、播送生产

Routing 路由模式

  • 路由模式是用Rabbit最罕用的一种模式。
  • Producer公布了一个Exchange,这个Exchange的类型是Direct,在Message中指定RoutingKey,并设置一个非空的值,接下来申明一些Queue,这些 Queue在申明和绑定Exchange的时候,须要指定Binding,音讯在路由的时候判断音讯里的RoutingKey和BindingKey是不是equal,如果是对等的就能够路由过去。
  • 相似tag过滤的音讯散发场景。
  • 官网解说
  • 对齐rocketmq、pulsar的tag过滤生产

Topic 通配符模式

  • 路由模式的升级版,反对通配符匹配。
  • Exchange类型为Topic。
  • 匹配规定不是正则表达式,是AMQP本人的语法。
  • 官网解说

Header模式

  • 不罕用,匹配规定不基于RoutingKey,而是基于HeaderBody.Properties.Headers中的键值对。
  • 反对齐全匹配所有键值对。
  • 反对只匹配一个键值对。

RPC模式

  • RPC模式并不罕用,基于回复队列。
  • 生产者和消费者采纳一问一答的模式。
  • 等价于RPC的request-response模型。
  • 官网解说

生产模型

生产模型也是应用一个音讯零碎所须要特地关怀的一环,在业务的应用过程中,更多地会关注一条音讯从生产到投递至消费者整个过程中都经验了什么,整个音讯的申明周期是如何闭环的?

上面次要从TDMQ RabbitMQ版的实现来分析RabbitMQ协定的音讯生命周期。

从音讯的生命周期对待生产模型

  • 已投递未Ack:Consumer独占,直到Consumer触发Ack或者Consumer断开。
  • Ack音讯:标记已生产,位点后退。
  • Nack音讯:底层操作等价于Ack,会依据配置转发到死信Exchange,否则抛弃。
  • Requeue:音讯放回队头,待下次投递。

从外部外围组件看生产模型

  • Queue:负责存储原始音讯数据,按序存储。
  • RedeliveryTracker:负责记录Consumer端Requeue的音讯,并触发从新投递,标识投递次数。
  • Dispatcher:负责管理连贯Queue的所有Consumer,负责音讯的负载平衡、散发、进度治理等。
  • Limiter:QoS限流器,基于Unack数限流,而不是QPS,响应上方音讯生命周期。
  • Unack Tracker:跟踪以后Channel中已投递未Ack的音讯。

从这张图能够获取那些信息?

  • 一个Queue能够被不同Connection连贯、被同一个Connection的不同Channel连贯。
  • 一个Channel中能够启动两个Consumer连贯同一个Queue。
  • QoS限流作用域为Channel,即一个Channel中创立的多个Cconsumer享有雷同的配额。
  • 如果BasicQoS Global设置为true,那么同一个Channel中的Consumer用尽配额,该Channel下的所有Consumer全副阻塞,无奈接管新音讯。
  • Unack追踪器也是Channel作用域,故一个Channel敞开,被该Channel独占的所有未Ack音讯全副回收到Queue级别的跟踪器,进行全局重投递。
  • basic指令集: https://www.rabbitmq.com/amqp...
  • Consumer Prefetch: https://www.rabbitmq.com/cons...

金融级用法

  • 音讯确认:发送反馈,给予Producer发送胜利的确认。
  • 备选Exchange:发送胜利的音讯无奈匹配任何Binding的场景。
  • 音讯回退:音讯无奈匹配任何Binding时退回到Producer。
  • 重投递:网络谬误、Consumer端宕机、业务解决偶发谬误等场景,重试生产复原。
  • 死信Exchange:业务多次重试、长时间无奈胜利,放入死信,待人工解决或者下一步的自动化修改or告警零碎。

性能点比照

通过上述阐明,你应该能利用RabbitMQ的性能点,联合本人的业务场景组织一个绝对正当的生产生产拓扑。
除了下面提到的性能点,RabbitMQ自身还提供了很多其余性能,上面次要列举一部分比照,可供参考和借鉴:

通道类

性能点阐明TDMQ反对状况
认证和受权基于User/Password的登录鉴权机制。整合Pulsar本身的JWT(Role+Token)机制进行对齐
连贯协商机制连贯握手协商连贯通信参数。齐全对齐RabbitMQ原生
认证和受权Vhost维度配置和User的权限关系。AMQP SDK应用层面齐全对齐
限流协商机制(QoS)基于Unack数进行配额限度。齐全对齐RabbitMQ原生
  • 留神:QoS机制RabbitMQ的实现是和规范AMQP协定有出入的,咱们抉择对齐RabbitMQ而不是AMQP标准,咱们也认为RabbitMQ的模式较正当,详见https://www.rabbitmq.com/cons...

Exchange类

性能点阐明TDMQ反对状况
Exchange绑定ExchangeRabbitMQ在AMQP协定上的扩大,使Exchange不局限于只绑定Queue,借此能够构建出更加简单的拓扑逻辑。暂未反对,排期中
死信ExchangeQueue的扩大参数,用于Queue中抛弃音讯时转发至死信Exchange。齐全对齐RabbitMQ原生
备选ExchangeExchange的扩大参数,用于音讯发送至Exchange时,无奈匹配任何路由规定到上游Queue,转发至备选Exchange。齐全对齐RabbitMQ原生

Queue类

性能点阐明TDMQ反对状况
优先队列音讯可设置优先级,同时达到的音讯可依据优先级投递,是一种局部性毁坏先入先出机制的性能。暂未反对,排期中
独占队列申明队列只能被申明的Connection实体所连贯,通常和长期队列配合应用。暂未反对,排期中
长期队列随机生成一个长期队列名,可用于以后过程专用,通常配合独占队列和AutoDelete一起应用。暂未反对,排期中
回复队列用于申明音讯Producer解决实现后,向Producer进行回包的队列,以此实现一问一答的通信模型。暂未反对,排期中
TTL针对音讯设置TTL(time to live),过期未投递的音讯将会被抛弃 or 进入死信。目前反对Vhost级别的TTL机制
镜像队列RabbitMQ为了解决单点贮存问题而引入的,为了实现队列音讯多正本存储。TDMQ人造多正本分布式存储,不须要该性能

收发机制类

性能点阐明TDMQ反对状况
音讯确认音讯在Broker胜利存储后,回包Producer,进行发送胜利确认。齐全对齐RabbitMQ原生
事务音讯音讯确认性能呈现前的发送确认机制,性能很差,不倡议应用。暂未反对,待定
提早音讯音讯发送胜利后,提早肯定工夫后才进行投递。齐全对齐RabbitMQ原生
RPC基于回复队列封装出的一问一答模型,应用场景较少,倡议用支流RPC框架。暂未反对,待定

参考

  • RabbitMQ协定官网文档
  • RabbitMQ官网性能介绍
  • RabbitMQ协定指令集
  • RabbitMQ官网教程
  • RabbitMQ官网Demo

后记

通过这篇文章,心愿能对RabbitMQ进行肯定水平的科普,也从一个从0到1设计一个RabbitMQ Broker的开发的角度,浅析了一些RabbitMQ的一些生产模型细节,补充点以后网络上对这部分细节的缺漏,可能能够起到一些启发作用。

后续,咱们将会着重分享,咱们如何在apache pulsar生态上构建出一套齐全对齐RabbitMQ协定的高性能、高可用、云原生音讯队列,相比原生RabbitMQ,咱们有何劣势,以及咱们在过程中遇到的问题,产生的思考。

敬请期待~