新来个技术总监,把 RabbitMQ 讲得那叫一个透彻,佩服( 二 )

  • Binding:绑定,交换器和消息队列之间的虚拟连接,绑定中可以包含一个或者多个RoutingKey 。
  • RoutingKey:路由键,生产者将消息发送给交换器的时候,会发送一个RoutingKey,用来指定路由规则,这样交换器就知道把消息发送到哪个队列 。路由键通常为一个“.”分割的字符串,例如“com.rabbitmq” 。
  • Queue:消息队列,用来保存消息,供消费者消费 。
  • 2.2 工作原理AMQP 协议模型由三部分组成:生产者、消费者和服务端,执行流程如下:
    1. 生产者是连接到 Server,建立一个连接,开启一个信道 。
    2. 生产者声明交换器和队列,设置相关属性,并通过路由键将交换器和队列进行绑定 。
    3. 消费者也需要进行建立连接,开启信道等操作,便于接收消息 。
    4. 生产者发送消息,发送到服务端中的虚拟主机 。
    5. 虚拟主机中的交换器根据路由键选择路由规则,发送到不同的消息队列中 。
    6. 订阅了消息队列的消费者就可以获取到消息,进行消费 。

    新来个技术总监,把 RabbitMQ 讲得那叫一个透彻,佩服

    文章插图
    2.3 常用交换器RabbitMQ常用的交换器类型有direct、topic、fanout、headers四种:
    • Direct Exchange:见文知意,直连交换机意思是此交换机需要绑定一个队列,要求该消息与一个特定的路由键完全匹配 。简单点说就是一对一的,点对点的发送 。

    新来个技术总监,把 RabbitMQ 讲得那叫一个透彻,佩服

    文章插图
    • Fanout Exchange:这种类型的交换机需要将队列绑定到交换机上 。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上 。很像子网广播,每台子网内的主机都获得了一份复制的消息 。简单点说就是发布订阅 。

    新来个技术总监,把 RabbitMQ 讲得那叫一个透彻,佩服

    文章插图
    • Topic Exchange:直接翻译的话叫做主题交换机,如果从用法上面翻译可能叫通配符交换机会更加贴切 。这种交换机是使用通配符去匹配,路由到对应的队列 。通配符有两种:"*" 、 "#" 。需要注意的是通配符前面必须要加上"."符号 。
    • *符号:有且只匹配一个词 。比如 a.*可以匹配到"a.b"、"a.c",但是匹配不了"a.b.c" 。
    • #符号:匹配一个或多个词 。比如"rabbit.#"既可以匹配到"rabbit.a.b"、"rabbit.a",也可以匹配到"rabbit.a.b.c" 。

    新来个技术总监,把 RabbitMQ 讲得那叫一个透彻,佩服

    文章插图
    • Headers Exchange:这种交换机用的相对没这么多 。它跟上面三种有点区别,它的路由不是用routingKey进行路由匹配,而是在匹配请求头中所带的键值进行路由 。创建队列需要设置绑定的头部信息,有两种模式:全部匹配和部分匹配 。如上图所示,交换机会根据生产者发送过来的头部信息携带的键值去匹配队列绑定的键值,路由到对应的队列 。

    新来个技术总监,把 RabbitMQ 讲得那叫一个透彻,佩服

    文章插图
    2.4 消费原理我们先看几个基本概念:
    • broker:每个节点运行的服务程序,功能为维护该节点的队列的增删以及转发队列操作请求 。
    • master queue:每个队列都分为一个主队列和若干个镜像队列 。
    • mirror queue:镜像队列,作为master queue的备份 。在master queue所在节点挂掉之后,系统把mirror queue提升为master queue,负责处理客户端队列操作请求 。注意,mirror queue只做镜像,设计目的不是为了承担客户端读写压力 。
    集群中有两个节点,每个节点上有一个broker,每个broker负责本机上队列的维护,并且borker之间可以互相通信 。集群中有两个队列A和B,每个队列都分为master queue和mirror queue(备份) 。那么队列上的生产消费怎么实现的呢?
    新来个技术总监,把 RabbitMQ 讲得那叫一个透彻,佩服

    文章插图
    对于消费队列,如下图有两个consumer消费队列A,这两个consumer连在了集群的不同机器上 。RabbitMQ集群中的任何一个节点都拥有集群上所有队列的元信息,所以连接到集群中的任何一个节点都可以,主要区别在于有的consumer连在master queue所在节点,有的连在非master queue节点上 。
    因为mirror queue要和master queue保持一致,故需要同步机制,正因为一致性的限制,导致所有的读写操作都必须都操作在master queue上(想想,为啥读也要从master queue中读?和数据库读写分离是不一样的),然后由master节点同步操作到mirror queue所在的节点 。即使consumer连接到了非master queue节点,该consumer的操作也会被路由到master queue所在的节点上,这样才能进行消费 。


    推荐阅读