zoukankan      html  css  js  c++  java
  • RabbitMQ实际使用场景

    1.说一说什么是RabbitMQ,你对它有什么理解?

      RabbitMq 是一个开源的 基于AMQP协议实现的一个完整的企业级消息中间件,服务端语言由Erlang(面向并发编程)语言编写 对于高并发的处理有着天然的优势,客户端支持非常多的语言。

      RabbitMq 如同Redis一样,它也是采用c/s架构 由服务端 与客户端组成。

    2.RabbitMQ有什么优缺点?

      优点:解耦,异步,削峰;

      缺点:降低了系统的稳定性,增加了系统的复杂性,加入了消息队列,要考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。

    3.如何保证RabbitMQ的高可用?

      RabbitMQ对于高可用是基于主从的方式进行实现. 其有三种工作模式: 单机模式普通集群模式镜像集群模式

      单机模式:生产环境不适用。

      普通集群模式:在多个服务器上部署多个MQ实例,每台机器一个实例,创建的每一个queue,只会存在一个MQ实例上. 但是每一个实例都会同步queue的元数据(即queue的标识信息). 当在进行消费的时候, 就算 连接到了其他的MQ实例上, 其也会根据内部的queue的元数据,从该queue所在实例上拉取数据过来.这种模式性能开销巨大.容易造成单实例的性能瓶颈. 并且如果真正有数据的那个queue的实例宕机了. 那么其他的实例就无法进行数据的拉取.

      镜像集群模式:这种模式才是高可用模式. 与普通集群模式的主要区别在于. 无论queue的元数据还是queue中的消息都会同时存在与多个实例上.要开启镜像集群模式,需要在后台新增镜像集群模式策略. 即要求数据同步到所有的节点.也可以指定同步到指定数量的节点.缺点:1.性能开销大,2.无法线性扩容。

    4.如何保证RabbitMQ不被重复消费?

      正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除;但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者,这就导致了消息被重复消费。

      针对以上问题,一个解决思路是:保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响;保证消息等幂性;比如:在写入消息队列的数据做唯一标示,消费消息时,根据唯一标识判断是否消费过;

    5.如何保证RabbitMQ消息的可靠传输?

      生产者丢失消息:从生产者弄丢数据这个角度来看,RabbitMQ提供transaction和confirm模式来确保生产者不丢消息;

      transaction机制就是说:发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事务就会回滚(channel.txRollback()),如果发送成功则提交事务(channel.txCommit())。

      一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后;rabbitMQ就会发送一个ACK给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了;如果rabbitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。

      消息队列丢数据:消息持久化。

        处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。

      如何进行消息持久化?

        1.将queue的持久化标识durable设置为true,则代表是一个持久的队列

        2.发送消息的时候将deliveryMode=2

        这样设置以后,即使rabbitMQ挂了,重启后也能恢复数据

      消费者丢失消息:消费者丢数据一般是因为采用了自动确认消息模式,改为手动确认消息即可!

        消费者在收到消息之后,处理消息之前,会自动回复RabbitMQ已收到消息;如果这时处理消息失败,就会丢失该消息;

        解决方案:处理消息成功后,手动回复确认消息。

    6.如何保证RabbitMQ消息的顺序性:

      1.单线程消费保证消息的顺序性;

      2.对消息进行编号,消费者处理消息是根据编号处理消息;

    7.RabbitMQ是基于什么传输的?

      由于TCP连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。RabbitMQ使用信道的方式来传输数据。信道是建立在真实的TCP连接内的虚拟连接,且每条TCP连接上的信道数量没有限制。

    8.RabbitMQ的消息是如何路由的?

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

      1.消息发布到交换器时,消息将拥有一个路由键(routing key),在消息创建时设定。

      2.通过队列路由键,可以把队列绑定到交换器上。

      3.消息到达交换器后,RabbitMQ会将消息的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规则)。如果能够匹配到队列,则消息会投递到相应队列中;如果不能匹配到任何队列,消息将进入 “黑洞”。

     

  • 相关阅读:
    sql左外连接、右外连接、group by、distinct(区别)、intersect(交叉)、通配符、having
    nvarchar,varchar 区别
    链家笔试链家——找寻最小消费获取最大平均分java
    利用SpringAOP 实现 日志输出
    AOP 学习笔记
    Spring AOP中pointcut expression表达式解析
    基于@Aspect的AOP配置
    URI 中特殊字符处理
    给电脑设置视力保护色
    Spring不支持依赖注入static静态变量
  • 原文地址:https://www.cnblogs.com/wk-missQ1/p/13595876.html
Copyright © 2011-2022 走看看