Rabbitmq原理理解

rabbitmq特点

RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。

AMQP :Advanced Message Queue,高级消息队列协议。

  1. 可靠性(Reliability)
  2. 灵活的路由(Flexible Routing)
  3. 消息集群(Clustering)
  4. 高可用(Highly Available Queues)
  5. 多种协议(Multi-protocol)
  6. 多语言客户端(Many Clients)
  7. 管理界面(Management UI)
  8. 跟踪机制(Tracing)
  9. 插件机制(Plugin System)

rabbitmq概念模型

rabbtimq 消息模型

生产者 --> queue --> consumer

基本概念

  1. Message

    分为两部分:payload、label。payload为传输的数据,label可以理解为exchange的名字或者是一个tag。用来描述payload,rabbitmq讲根据这个label来决定message发送给谁。

  2. Publisher

    为生产者,负责生产数据,并把数据发送给Exchange

  3. Exchange

    Exchange接受到数据后,根据Routing Key,来指定消息的路由规则。当然Routing Key需要与Exchange Type及Binding key联合使用才能最终生效,根据路由规则,匹配查询表中的routing key,分发消息到queue中。

  4. Binding

    在绑定(Binding)Exchange与Queue的同时,一般会指定一个Binding key;

    但Binding key并不是在所有情况下都生效,它依赖于Exchange Type

  5. Queue

    rabbitmq内部对象,用于存储消息。一个消息可以被同时copy到多个queue中。

    如果queue不存在,当然Consumer不会得到任何的Message。那么Producer Publish的Message会被丢弃。所以,还是为了数据不丢失,Consumer和Producer都try to create the queue!反正不管怎么样,这个接口都不会出问题。

    queue对load balance的处理是完美的。对于多个Consumer来说,RabbitMQ 使用循环的方式(round-robin)的方式均衡的发送给不同的Consumer。

  6. Connection

    Connection就是一个TCP的连接,Producer和Consumer都是通过TCP连接到RabbitMQ Server的

  7. Channel

    Channel是建立在上述的TCP连接中,因为建立TCP Connection的开销将是巨大的,所以是节省开销;

    Channel是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等

  8. Consumer

    如果有多个消费者同时订阅同一个Queue中的消息,Queue中的消息会被平摊给多个消费者

  9. Virtual Host

    当多个不同的用户使用同一个RabbitMQ server提供的服务时,可以划分出多个vhost,每个用户在自己的vhost创建exchange/queue

  10. Broker

AMQP中的消息路由

Exchange类型

Exchange分发消息时根据类型的不同分发策略有区别,目前共四种类型:direct、fanout、topic、headers 。

  1. direct(单播模式)

    消息中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器就将消息发到对应的队列中。路由键与队列名完全匹配,如果一个队列绑定到交换机要求路由键为“dog”,则只转发 routing key 标记为“dog”的消息,不会转发“dog.puppy”,也不会转发“dog.guard”等等。它是完全匹配、单播的模式。

  2. fanout(广播模式)

    每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。fanout 交换器不处理路由键,只是简单的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。fanout 类型转发消息是最快的。

  3. topic(匹配模式)

    topic 交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号“#”和符号“.”,#匹配0个或多个单词,匹配不多不少一个单词。

  4. headers
    header匹配AMQP消息的header,而不是路由键。header与direct交换器完全一致。但是性能很差。很少使用。

rabbitmq消息可靠性

  1. Message durability(消息持久化)

    元数据、消息需要持久化到磁盘;

    磁盘节点:持久化的消息在到达队列时就被写入到磁盘,并且如果可以,持久化的消息也会在内存中保存一份备份,这样可以提高一定的性能,只有在内存吃紧的时候才会从内存中清除;

    内存节点:非持久化的消息一般只保存在内存中,在内存吃紧的时候会被换入到磁盘中,以节省内存空间;

  2. Message acknowledgment(消息确认机制)

    在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出现其他意外)的情况,这种情况下就可能会导致消息丢失。为了避免这种情况发生,我们可以要求消费者在消费完消息后发送一个回执给RabbitMQ,RabbitMQ收到消息回执(Message acknowledgment)后才将该消息从Queue中移除。

    如果一个Queue没被任何的Consumer Subscribe(订阅),当有数据到达时,这个数据会被cache,不会被丢弃。当有Consumer时,这个数据会被立即发送到这个Consumer。这个数据被Consumer正确收到时,这个数据就被从Queue中删除。

    那么什么是正确收到呢?通过ACK。每个Message都要被acknowledged(确认,ACK)。我们可以显示的在程序中去ACK,也可以自动的ACK。如果有数据没有被ACK,那么RabbitMQ Server会把这个信息发送到下一个Consumer。

  3. 生产者消息确认机制

    • 通过AMQP提供的事务机制实现
    • 通过生产者消息确认机制(publisher confirm)实现

参考:https://zhuanlan.zhihu.com/p/63700605

你可能感兴趣的:(中间件,rabbitmq,分布式)