1.什么是RabbitMq

RabbitMq是一个由Erlang语言编写,基于AMQP协议,基于分布式部署,可扩展、高可用的开源消息队列中间件。与Kafka不同的是,RabbitMq的主要功能就是消息的接收、存储、转发。
RabbitMq支持点对点(一对多)、发布/订阅模式(一对多)、广播(多对多)等多种消息发布消费模式

2.RabbitMq的特点

  1. 可靠性:RabbitMq可通过队列持久化,交换机持久化,消息持久化及ACK响应等机制保证可靠性
  2. 高可用性:RabbitMq基于分布式模式部署,多个Rabbit服务构成一个集群。队列会在每一个Rabbit服务器上进行镜像备份,类似于Kafka的多副本机制,进一步提高了RabbitMq的高可用性
  3. 支持多种语言和多种协议:RabbitMq几乎支持所有的编程语言,并且还支持AMQT、MQTT、STOMP等多种协议
  4. 天然的可视化管理界面:RabbitMq本身就具备一套完整的、友好的可视化界面、无需额外进行可视化工具的下载
  5. 更纯粹的消息队列:相较于Kafka,RabbitMq更像是一个功能完备的消息队列,而Kafka追求的是高吞吐量、大数据量以及数据的流式处理

    3.RabbitMq的适用场景

  6. 服务解耦:消息队列的传统应用场景之一。对于Rabbit这样一个更加纯粹的消息队列,是必须支持的场景。至于什么是服务解耦,很好理解,A系统与B系统不再直接相互调用,而是通过消息队列来进行服务之间的沟通。这样即使其中的服务宕机,也不会造成系统立即不可用,起到了一个很好的缓冲作用

  7. 异步处理:也是消息队列的传统应用场景之一。异步的方式无外乎多线程与消息队列两种,而RabbitMq同样可以用于异步处理。例如常见的验证码发送,邮件发送等功能,使用RabbitMq用来异步处理十分方便
  8. 流量削峰填谷:也是消息队列的传统应用场景之一。将请求存入消息队列,服务以一个恒定的速度消费消息,从而确保流量峰值也不会冲垮服务,起到一个中间缓冲的作用
  9. 日志处理:与Kafka一样,RabbitMq同样适用于异步日志处理。只不过相对来说,RabbitMq的吞吐量要逊色与Kafka一些

    4.RabbitMq的核心概念

    服务端

    Broker

    一个RabbitMq服务实例即是一个Broker,这一点与Kafka一样。多个Broker共同构成一个RabbitMq集群,并且通常来说,每个Broker都部署在不同的服务器上

    Virtual Host

    与Kafka不同的是,RabbitMq中存在着更为严格的权限校验机制,同一个服务器适配多个用户,这种模式称为多租户模式。
    为了数据的安全性、隔离性以及适配多租户模式,RabbitMq中存在Virtual Host的概念,可以理解为虚拟主机(虚拟的Broker实例)。即在一个Broker内部存在多个Virtual Host,每一个Virtual Host对应一个用户

    Exchange

    交换机,RabbitMq中最重要的概念,负责将消息分发到对应的Queue
    生产者发送的消息首先就会到达Exchange中,再由Exchange根据相对应的分发规则或路由匹配,将消息发送到对应的Queue中
    需要注意的是,Exchange并不进行消息的持久化,只负责消息的分发,并且一个Virtual Host中不能有重名的Exchange
    RabbitMq目前常用的Exchange包括如下几种

    Direct Exchange(直接交互交换机)

    只会将消息转发到消息路由键与绑定路由键完全匹配的队列上,是一种完全匹配,单播模式的交互机。可以实现点对点模式的消息发布与消费

    Fanout Exchange(扇形交换机)

    将消息转发到所有绑定的队列上,是一种发布/订阅模式的交互机。可以实现一个消息被多个消费者消费

    Topic Exchange(主题交换机)

    只会将消息转发到消息路由键与绑定路由键模糊匹配的队列上,支持两种通配符。(#:匹配1个或多个词,*:只能匹配一个词)。是一种模糊匹配,多播模式的交互机
    通过路由通配符来控制消息分发到哪些队列,相当于一种介于Direct Exchange(直接交互交换机)和Fanout Exchange(扇形交换机)之间的交换机

    Default Exchang(默认交换机)

    本质上是一个名字为””(空字符串)的直连交换机,所有创建的队列默认都会绑定到默认交换机上,binding_key与队列名称相同

    Queue

    消息队列,消息经过交互机转发后,会到达队列中,并在队列中持久化。但消息被消费者消费后,消息会删除。这一点与Kafka不同
    RabbitMq中Queue同样存在备份机制,通常来说,一个RabbitMq集群每一个节点上的消息信息应该是一致的。主节点上的队列称为Master Queue,从节点上的队列称为Mirror Queue,类似于Kafka中副本的概念。其中Master Queue负责处理客户端的读写请求,Mirror Queue只负责做Master Queue的备份,这一点与Kafka也是一样的
    需要注意的是,Exchange与Queue是一个多对多的概念

    Binding

    交换机与队列的虚拟绑定关系,决定了交换机需要把消息发送到哪个队列上。
    Binding中包含Routing_key,保存在交互机的查询表中,用于Message的分发查询依据

    Message

    消息,RabbitMq中的重要概念,由两部分组成

  10. 消息头:由一系列可选属性构成,包括 routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(该消息需不需要持久性存储等)

  11. 消息体:具体的消息内容,不透明

    客户端

    Publisher

    生产者,产生消息并发送到Broker的Exchange,Exchange在根据对应的路由转发规则将消息发送到Queue

    Consumer

    消费者,负责从Queue中获取消息并消费

    Connection

    生产者/消费者与Broker之间的TCP网络连接

    Channel

    双工网络通道,可以理解为Connection的子集。
    因为如果每一次请求Broker都要新建一个连接,那么当消息量增大时,无论是Broker还是生产者/消费者,每次打开连接、关闭链接的开销都是极大的。这也会进一步影响RabbitMq的吞吐量
    所以,在Connection内部在分配一个Channel的概念,Channel一旦打开,除非链接关闭,不然一直存在。并且Channel之间相互隔离,确保每个Channel的独立性。消息的发布与消费都通过Channel来进行通信,从而实现一个TCP的连接的多路复用
    一个Connection可以对应打开多个Channel

    图示

    yuque_diagram.jpg
    如上图所示

  12. 存在1个RabbitMq实例,即1个Broker

  13. Broker中存在2个Visual Host。
  14. Visual Host1内有一个Exchange,2个Queue。2个Queue都绑定在Exchange上,Binding_key分别为Binding1和Binding2
  15. Visual Host2内有一个Exchange,1个Queue。Queue1通过Binding1绑定在Exchange上
  16. 存在1个Publisher,内有2个线程,2个线程对应在Connection中打开了2个Channel
  17. 该Publisher对应Visual Host1,向Visual Host1发送消息
  18. 存在1个Consumer,Consumer内有1个线程,1个线程对应在Connection中打开了1个Channel
  19. 该Consumer监听Visual Host1的2个Queue
  20. Queue中的Message包含2个部分,Header和Body

    5.Rabbit中的角色分类

    Administrator(超级管理员)

    可以登录控制台,可以对任意资源进行查看和管理,拥有最高权限

    Monitoring(监控者)

    可以登录控制台,可以对属于当前用户的资源进行查看和管理。可以查看其他用户的资源,但是不能管理

    Policymaker(策略制定者)

    可以登录控制台,可以对属于当前用户的资源进行查看和管理。

    management(普通管理员)

    可以登录控制台,可以对属于当前用户的资源进行查看

    no(普通用户)

    无法登录控制台,只作为普通的Publisher和Consuemr

    6.RabbitMq与Kafka对比

    语言方面

  • RabbitMq:由内在高并发的Erlang语言开发,用在实时的对可靠性要求比较高的消息传递上
  • kafka:采用Scala以及Java语言开发,它主要用于处理活跃的流式数据,大数据量的数据处理上

    顺序性方面

  • RabbitMq:可以实现全局消息的顺序性

  • Kafka:只能保证单一分区的消息有序,整个Topic无法保证消息有序

    消息持久化方面

  • RabbitMq:消息消费成功后就会删除,因此无法进行消息回溯消费

  • Kafka:消息长期持久化,Consumer通过Offsets来控制消费进度,支持消息回溯消费

    伸缩性方面

  • RabbitMq:无分区机制,因此相对来说不利于横向扩展。但是存在镜像队列机制,可以保证集群服务的稳定性

  • Kafka:存在分区以及副本机制,便于横向扩展以及纵向扩展,对于超大数据量的存储,一样可以很好的应对,所以相对来说吞吐量更高,伸缩性更好

    消息获取方面

  • RabbitMq:支持推/拉两种方式获取消息,默认为推模式

  • Kafka:支持拉模式获取消息

    消息处理多样性方面

  • RabbitMq:可以通过消息头设置消息优先级,并且可通过死信队列,延迟队列,优先级队列,惰性队列等多种队列,极其方便的实现消息的延迟发布,消息的异常重置

  • Kafka:主题与分区无特殊属性分类,无法天然支持延迟发布。对于消息丢失,重复等机制,也需要客户端从代码层面来参与才可以实现,没有RabbitMq用起来那么方便

    应用场景方面

  • RabbitMQ:用于提供一个高效、稳定、且多样的消息队列服务

  • kafka:用于超高吞吐量的流式数据以及非流式数据的处理

    7.RabbitMq控制台使用说明

    卷不动了老铁们。自己看吧:https://cloud.tencent.com/developer/article/1540246

    8.RabbitMq的集群类型

    单机模式

    最简单的部署模式,比较简单,开发环境和测试环境使用

    集群模式

    多个Broker部署在不同的服务器上,共同组成一个RabbitMq集群。但是每个队列都只会在本节点被创建,不会在其他节点创建。
    客户端与集群中的任意一个节点建立连接后,如果所操作的队列不在本节点,那么会由本节点将相关请求转发到队列所在节点
    本质上来说这并不是一个真正的高可用集群模式。因为一旦出现节点宕机,除非消息是持久化消息,不然就会造成消息的丢失。而且即使是持久化消息,也需要等到节点重启才可提供对外提供服务。
    所以相对来说,集群模式只能起到提高吞吐量的作用

    镜像模式

    与集群模式一样,也是多个Broker共同构成一个RabbitMq集群。与其不同的是,镜像模式下,一个队列可以同时在多个节点上创建并同步消息,队列之间的消息同步是阻塞式的。
    其中一个队列的Master副本负责与Publisher和Consumer进行数据交互,而Follow副本只负责进行数据备份,以及当主节点宕机后,重新选举为新的主节点
    需要注意的是,与集群模式一样。在镜像模式下,如果客户端与非主副本节点建立连接,请求同样需要由当前节点再次转发到主副本节点
    在镜像模式下,才实现了RabbitMq集群的高可用性以及稳定性