zoukankan      html  css  js  c++  java
  • rabbitmq简介

    RabbitMQ(Advanced Message Queuing Protocol,高级消息队列协议)是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用Erlang语言来编写的,并且RabbitMQ是基于AMQP协议的。

    一、消息队列使用场景

    1、异步通信(防止客户端阻塞)

    同步通信需要双方都在线,而使用消息队列,生产者可以将数据投放到消息队列中,等消费者在线了再取数据消费。

    服务在处理耗时长的请求时,可以先返回响应,告诉客户端收到请求了,正在处理。这样客户端就不会阻塞,可以做其他工作。等服务处理完请求,将处理结果投递到消息队列中,

    客户端订阅消息队列就能收到处理结果,根据处理结果做相应操作。

    2、解耦

    耦合度高的服务一般都是需要共享数据,通过消息队列可以实现数据共享,从而实现解耦。

    二、相关术语

    1、生产者

    消息的生产者。也是一个向交换器Exchange发送消息的应用程序。

    2、信道

    网络信道,是TCP里面的虚拟连接。几乎所有的操作都在Channel中进行, Channel是进行消息读写的通道。客户端可以建立多个Channel

    rabbitmq中多个信道共享一个TCP连接,避免tcp连接成为性能瓶颈。

    3、交换机

    接收生产者发送的消息,根据路由键转发消息到绑定的队列。

    4、队列

    消息队列,保存消息并将它们转发给消费者。它是消息的容器,也是消息的终点。一个消息可以投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列上将其取走。

    5、消费者

    消息的消费者。表示一个从消息队列中取得消息的应用程序

    6、BindingKey

    Exchange和Queue之间的虚拟连接,binding中可以包含routing key。

    一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。

    7、RoutingKey

    路由键。一个路由规则,虚拟机可用它来确定如何路由一个特定消息。

    队列通过路由键绑定到交换机。

    消息发送到MQ服务器时,消息将拥有一个路由键,即便是空的。RabbitMQ也会将其和绑定使用的路由键进行匹配。

    如果匹配,消息将投递到该队列;如果不匹配,消息将会进入黑洞。

    三、工作流程

    生产者创建与rabbitmq的tcp连接,将数据投递到交换机中,交换机根据数据的路由键找到绑定到该交换机的队列,将数据投递到该队列。

    消费者订阅响应的消息队列,收到消息后rabbitmq将数据发生给消费者。

    四、交换机类型

    1、direct(发布与订阅,完全匹配)

    消息的RoutingKey和和队列的BindingKey要完全一致,交换机才会把消息投递到该队列

    2、fanout(广播)

    交换机不管消息的RoutingKey,将消息投递到所有绑定到该交换机的队列中

    3、topic(主题,规则匹配)

    可以理解成路由模式,即根据消息的RoutingKey投递到匹配的BingdingKey队列中。

    4‘、header(key-value)

    根据key-value来投递消息。消息的key-value和队列的key-value相同才投递

    五、常见问题

    1、可靠性如何保证?

    投递过程中可能存在某个过程失败导致消息丢失。大概分成三种

    1.1、生产者投递过程失败导致消息丢失

    生产者在投递消息过程中,由于出现网络问题或者其他原因,导致消息未能到达交换机。

    如何解决:

    开启生产者确认机制即confirm,只有当生产者投递消息到交换机成功后,rabbitmq发送一个confirm确认给生产者,这样才算投递完成,否则,生产者需要重复投递,直到收到confirm确认。

    1.2、rabbitmq内部消息持久化失败导致消息丢失

    消息交换机后,进入队列中,由于rabbitmq突然崩溃或者其他原因,消息还没持久化导致消息丢失。

    如何解决:

    在开启生产者确认机制confirm时,只有当消息被正确投递到队列,并且已经持久化成功了,才给生产者发送ack。

    1.3、消费者接收消息失败导致消息丢失

    消息从队列中取出要投递给消费者时,由于网络问题或者其他原因,导致消息未能到达消费者

    如何解决:

    类似于生产者确认机制,开启消费者确认机制ack。当消息被消费者收到后,消费者发送acl给rabbitmq,才算投递成功。否则rabbitmq需要重复投递,直到收到消费者的ack消息,才将消息从队列中删除。

    这个过程可能存在多次消费问题,即消费者收到了消息,并且发送了ack,但是由于超时,rabbitmq没有收到ack,重新投递了消息。这种情况就会导致消费者多次消费同个消息。

    要求消费者实现幂等。即消费一次和消费多次是一样的结果。

  • 相关阅读:
    四、django rest_framework源码之频率控制剖析
    Ubuntu14.04配置记录
    尝试开始写博客
    用IDEA把SpringBoot项目打成jar发布项目
    IDEA创建springboot项目部署到远程Docker
    springboot 快速部署
    最详细的 Spring Boot 多模块开发与排坑指南
    SpringMVC的工作原理
    Dubbo最详解
    Zookeeper入门看这篇就够了
  • 原文地址:https://www.cnblogs.com/lgh344902118/p/14967333.html
Copyright © 2011-2022 走看看