RabbitMQ系列-概念介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/M_Joes_17/article/details/81001700

RabbitMQ概念详解

    消息包含两个部分:有效载荷(payload)和标签(label).

有效载荷:你想传输的数据(任何内容)标签: 用来描绘有效载荷,并通过它决定谁将获得消息的拷贝(一个交换器的名字和可选的主题标记)注:(消费者在收到消息的时候,它只得到消息的一部分:有效载荷)

    信道(channel):

你在应用程序和Rabbit代理服务器之间创建一条TCP链接,一旦TCP连接打开(你通过认证),应用程序就可以创建一条AMQP信道.信道是建立在"真实"TCP连接内的虚拟连接.AMQP命令都是通过信道发送出去的.每条信道都会被指派一个唯一ID(AMQP库会帮你记住ID).不论是发布消息,订阅队列或者接收消息,这些动作都是通过信道完成的.

    为什么不直接使用TCP发送AMQP命令?

主要在于对操作系统来说建立和销毁TCP会话是非常然贵的开销线程启动后,会在现成的连接上创建一条信道,也就是获得链接到私密通信路径,而不会给操作系统的TCP栈造成额外的负担,因此,你可以美妙成百上千次的创建信道而不会影响操作系统.在一条TCP链接上创建多少条信道是没有限制的(可以把其想象成一束光纤电缆).

    AMQP消息路由的三个组成部分:交换器,队列和绑定.

生产者把消息发布到交换器上;消息最终到达队列,并被消费者接收;绑定决定了消息如何从路由器到特定的队列.

    路由键(routing key)

队列通过路由键绑定到交换器.当你吧消息发送到代理服务器时,消息将拥有一个路由键,RabbitMQ会使用路由键进行匹配,如果匹配的话,那么消息将会投递到该队列.如果路由的消息不匹配任何绑定模式的话,消息将进入"黑洞".

    RabbitMQ中的四种交换器的类型:(以下每种类型实现了不同的路由算法)

  • direct : 如果路由键匹配的话,消息就被投递到对应的队列


服务器必须实现direct类型的交换器,包含一个空白字符串名称的默认交换器.
当声明一个队列的时候,它会自动绑定到默认的交换器,并以队列的名称作为路由键(前提是获得了信道)
basic_publish(msg,'', 'queue-name')  <第一个消息的内容,第二个指定了默认交换器,第三个是路由键>
  • fanout : 该交换器将收到的消息广播到绑定的队列上(一对多)


  • topic : 它使得来自不同源头的消息能够到达同一个队列.


  • headers:该交换器允许你匹配AMQP消息的header而非路由键,除此之外和direct交换器完全一致,但性能会差很多.

    扫描二维码关注公众号,回复: 2926806 查看本文章

    消费者通过以下两种方式从特定的队列中接收消息:

  1. basic.consume : 这样会将信道设置为接收模式,直到取消对队列的订阅为止.(自动接收消息)
  2. basic.get : 获取单挑消息而不是持续的订阅.如果需要获取更多的消息需要再次发送该命令.
      当存在多个消费者订阅同一个队列的时候,消息是如何分发的??

    当队列也拥有多个消费者的时候,队列接收到消息将以循环(round-robin)的方式发送给消费者.每条消息指挥发送给一个订阅的消费者.

    消息确认

消费者接收的每一条消息都必须进行确认.消费者必须通过AMQP的basic.ack命令显式的向Rabbit发送一个确认,或者在订阅的队列的时候将auto.ack参数设置为true.当设置为true时,消费者每次收到消息,rabbit将自动视为确认了消息.消费者正确返回了接收消息成功,Rabbit才能安全的将消息从队列中删除.

        异常
  1. 消费者接收一条消息,然后确认之前从Rabbit断开连接(或者从队列上取消订阅),RabbitMQ会认为这条消息会没有分发,然后重新发送给笑一个订阅的消费者.
  2. 如果程序有BUG而忘记确认消息的话,Rabbit将不会给该消费者发送更多的消息.这是因为上一条消息被确认之前,Rabbit会认为这个消费者并没有准备好接收小一条消息.(如果你的程序出来消息的内容非常的耗时,则你的程序可以延迟确认该消息,直到消息处理完成.这样可以防止Rabbit持续不断的消息涌向你的应用而导致过载)

    注意:消费者对消息的确认和告诉生产者消息以及被接收时两件毫无关系的事情

    消息拒绝

basic.reject : 允许消费者拒绝RabbitMQ发送的消息,
当reject命令的requeue参数设置为true时,RabbitMQ会将消息重新发送给下一个订阅的消费者
当reject命令的requeue参数设置为false时,RabbitMQ立即会将消息从队列中移除,而不是把他发送给新的消费者.

    创建队列(queue.declare)

        参数:
  1. exclusive: 设置为true的时候,队列将变为私有.此时只有你的应用程序才能够消费队列的消息.当你想要限制一个队列只有一个消费者的时候很有帮助
  2. auto-delete : 当最后一个消费者取消订阅的时候,对俄就会自动移除.如果你需要临时队列只为一个消费者服务的话,请结合使用auto-delete和exclusive.当消费者断开连接的时候,队列就被删除了
  3. passive : 为true,如果队列存在,那么queue.declare命令会返回成功.如果队列不存在的话,queue,declare命令不会创建队列而会返回一个错误.

    队列应该由生产者创建还是消费者创建??

前提是要想清楚消息的生产者能否承担的起丢失消息.发送的消息如果路由到了不存在的队列的话,Rabbit会忽略他们,因此,如果你不能承担的起消息进入"黑洞"而丢失的话,你的生产者和消费者就都应该尝试去创建队列.当承担的起消息的丢失,你可以只让自己的消费者来创建队列.


猜你喜欢

转载自blog.csdn.net/M_Joes_17/article/details/81001700