RabbitMQ笔记

1.中间件应具有如下的一些特点:
(1)满足大量应用的需要
(2)运行于多种硬件和OS平台
(3)支持分布计算,提供跨网络、硬件和OS平台的透明性的应用或服务的交互
(4)支持标准的协议
(5)支持标准的接口

 2.学习目标?
什么是消息中间件
什么是协议
什么是持久化
消息分发
消息的高可用
消息的集群
消息的容错
消息的冗余

3.何谓分布式系统呢:

通俗一点:就是一个请求由服务器端的多个服务(服务或者系统)协同处理完成。
   和单体架构不同的是,单体架构是一个请求发起jvm调度线程(确切的是tomcat线程池)分配线程Thread来处理请求直到释放,
   而分布式系统是:一个请求是由多个系统共同来协同完成,jvm和环境都可能是独立。


4.消息中间件是什么?
1:利用可靠的消息传递机制进行系统和系统直接的通讯
2:通过提供消息传递和消息的排队机制,它可以在分布式系统环境下进行通讯。

5.消息中间件应用的场景?
    1:跨系统数据传递
    2:高并发的流量削峰
    3:数据的分发和异步处理
    4:大数据分析与传递
    5:分布式事务
    比如你有一个数据要进行迁移或者请求并发过多的时候,比如你有10W的并发请求下订单,
    我们可以在这些订单入库之前,我们可以把订单请求堆积到消息队列中,让它稳健可靠的入库和执行。

6.常见的消息中间件
       ActiveMQ、RabbitMQ、Kafka、RocketMQ等。

7. 消息中间件的本质及设计?
        它是一种接受数据,接受请求、存储数据、发送数据等功能的技术服务。

       MQ消息队列:负责数据的接受,存储和传递,所以性能要高于普通服务和技术。

8.消息中间件的核心组成部分?
      1:消息的协议
      2:消息的持久化机制
      3:消息的分发策略
       4:消息的高可用,高可靠
       5:消息的容错机制

9.消息队列的协议?
       网络协议的三要素:
          1.语法。语法是用户数据与控制信息的结构与格式,以及数据出现的顺序。
          2.语义。语义是解释控制信息每个部分的意义。它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应。
          3.时序。时序是对事件发生顺序的详细说明。

  所有的中间件技术都是基于tcp/ip协议基础之上构建新型的协议规范,只不过rabbitmq遵循的是amqp。

10.面试题:为什么消息中间件不直接使用http协议呢?
1: 因为http请求报文头和响应报文头是比较复杂的,包含了cookie,数据的加密解密,状态码,响应码等附加的功能,但是对于一个消息而言,我们并不需要这么复杂,也没有这个必要性,它其实就是负责数据传递,存储,分发就行,一定要追求的是高性能。尽量简洁,快速。
2:大部分情况下http大部分都是短链接,在实际的交互过程中,一个请求到响应很有可能会中断,
中断以后就不会就行持久化,就会造成请求的丢失。这样就不利于消息中间件的业务场景,因为消息中间件可能是一个长期的获取消息的过程,出现问题和故障要对数据或消息就行持久化等,目的是为了保证消息和数据的高可靠和稳健的运行。


11.RabbitMQ的协议是AMQP协议,AMQP协议的特性?
       特性:
         1:分布式事务支持。
          2:消息的持久化支持。
         3:高性能和高可靠的消息处理优势。

12.MQTT协议:消息队列是IBM开放的一个即时通讯协议,物联网系统架构中的重要组成部分。
        特点:
           1:轻量
           2:结构简单
           3:传输快,不支持事务
           4:没有持久化设计。
        应用场景:
            1:适用于计算能力有限
            2:低带宽
            3:网络不稳定的场景。
      支持者: RabbitMQ(默认是不开放的,要打开他的支持,才开放)

13.Kafka协议?(不支持事务)
       Kafka协议是基于TCP/IP的二进制协议。消息内部是通过长度来分割,由一些基本数据类型组成。
        特点是:
           1:结构简单
           2:解析速度快
           3:无事务支持
           4:有持久化设计

14.消息队列持久化?
       持久化
     简单来说就是将数据存入磁盘,而不是存在内存中随服务器重启断开而消失,使数据能够永久保存。

15.消息的分发策略?
       MQ消息队列有如下几个角色?
         1:生产者
         2:存储消息
         3:消费者
     那么生产者生成消息以后,MQ进行存储,消费者是如何获取消息的呢?
       一般获取数据的方式无外乎推(push)或者拉(pull)两种方式,典型的git就有推拉机制,我们发送的http请求就是一种典型的拉取数据库数据返回的过程。
        而消息队列MQ是一种推送的过程,而这些推机制会适用到很多的业务场景也有很多对应推机制策略。

      消息分发策略的机制?
          1.发布订阅
           2.轮询分发 (没有顺序的,都会是公平的,不论你的服务器的性能是怎么样的)自动应答
          3.公平分发  (有倾斜性,谁的性能好,给谁分发的就多一点) 手动应答
          4.重发
           5.消息拉取

16.消息的高可用和高可靠?
        1.什么是高可用机制?
             所谓高可用:是指产品在规定的条件和规定的时刻或时间内处于可执行规定功能状态的能力。
             当业务量增加时,请求也过大,一台消息中间件服务器的会触及硬件(CPU,内存,磁盘)的极限,
          一台消息服务器你已经无法满足业务的需求,所以消息中间件必须支持集群部署。来达到高可用的目的。

       2.  集群模式1 - Master-slave主从共享数据的部署方式:
              解说:生产者将消费发送到Master节点,所有的都连接这个消息队列共享这块数据区域,Master节点负责写入,一旦Master挂掉,slave节点继续服务。从而形成高可用。

        3.集群模式2 - Master- slave主从同步部署方式:
             解释:这种模式写入消息同样在Master主节点上,但是主节点会同步数据到slave节点形成副本,和zookeeper或者redis主从机制很类同。这样可以达到负载均衡的效果,如果消费者有多个这样就可以去不同的节点就行消费,消息的拷贝和同步会占用很大的带宽和网络资源。在后续的rabbitmq中会有使用。

        4.集群模式3 - 多主集群同步部署模式:
              解释:如果你插入的数据是broker-1中,元数据信息会存储数据的相关描述和记录存放的位置(队列)。
              它会对描述信息也就是元数据信息就行同步,如果消费者在broker-2中进行消费,发现自己几点没有对应的消息,可以从对应的元数据信息中去查询,然后返回对应的消息信息,场景:比如买火车票或者黄牛买演唱会门票,比如第一个黄牛有顾客说要买的演唱会门票,但是没有但是他会去联系其他的黄牛询问,如果有就返回。

        5.集群模式5 Master-slave与Breoker-cluster组合的方案:
              解释:实现多主多从的热备机制来完成消息的高可用以及数据的热备机制,在生产规模达到一定的阶段的时候,这种使用的频率比较高。
            

      反正终归三句话:
       1:要么消息共享,
       2:要么消息同步
       3:要么元数据共享

17.什么是高可靠机制?
       所谓高可靠是指:是指系统可以无故障低持续运行,比如一个系统突然崩溃,报错,异常等等并不影响线上业务的正常运行,出错的几率极低,就称之为:高可靠。
       在高并发的业务场景中,如果不能保证系统的高可靠,那造成的隐患和损失是非常严重的。

18.如何保证中间件消息的可靠性呢?
      可以从两个方面考虑:
        1:消息的传输:通过协议来保证系统间数据解析的正确性。
         2:消息的存储可靠:通过持久化来保证消息的可靠性。

19.RabbitMQ的入门安装?
        1. 什么是RabbitMQ?
            RabbitMQ是一个开源的遵循AMQP协议实现的基于Erlang语言编写,支持多种客户端(语言)。用于在分布式系统中存储消息,转发消息,具有高可用,高可扩性,易用性等特征。
        2.启动rabbitmq服务?
               # 启动服务
               > systemctl start rabbitmq-server
    # 查看服务状态
    > systemctl status rabbitmq-server
    # 停止服务
    > systemctl stop rabbitmq-server
    # 开机启动服务
    > systemctl enable rabbitmq-server
         3.rabbitmq的用户命令?
                rabbitmqctl add_user 账号 密码
    rabbitmqctl set_user_tags 账号 administrator
    rabbitmqctl change_password Username Newpassword 修改密码
    rabbitmqctl delete_user Username 删除用户
    rabbitmqctl list_users 查看用户清单
    rabbitmqctl set_permissions -p / 用户名 ".*" ".*" ".*" 为用户设置administrator角色
    rabbitmqctl set_permissions -p / root ".*" ".*" ".*"

20. 使用docker安装rabbitmq?
       1.docker的相关命令?
            # 启动docker:
    systemctl start docker
           # 停止docker:
    systemctl stop docker
           # 重启docker:
    systemctl restart docker
           # 查看docker状态:
    systemctl status docker
          # 开机启动:  
    systemctl enable docker
    systemctl unenable docker
          # 查看docker概要信息
    docker info
          # 查看docker帮助文档
    docker --help
 
     2.  额外Linux相关排查命令?
          > more xxx.log  查看日记信息
          > netstat -naop | grep 5672 查看端口是否被占用
          > ps -ef | grep 5672  查看进程
          > systemctl stop 服务

21. RabbitMQ的角色分类?
        1.  management:查看自己相关节点信息
        2.Policymaker  :包含management所有权限;查看和创建和删除自己的虚拟机节点。
        3. Monitoring:查看所有的虚拟机节点,但是只能看,不能删除修改。
        4.Administrator: 最高权限

22.  RabbitMQ入门案例 - Simple 简单模式?
          使用连接 和  通道  队列 进行
      先关通道,再关连接
      

     /*
             *  如果队列不存在,则会创建
             *  Rabbitmq不允许创建两个相同的队列名称,否则会报错。
             *
             *  @params1: queue 队列的名称
             *  @params2: durable 队列是否持久化  
             *  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭
             *  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。
             *  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。
             * */
     channel.queueDeclare("queue1", false, false, false, null);

      面试题: // 7: 发送消息给中间件rabbitmq-server
            // @params1: 交换机exchange
            // @params2: 队列名称/routing
            // @params3: 属性配置
            // @params4: 发送消息的内容
      面试题:可以存在没有交换机的队列吗? 不可能,虽然没有指定交换机,但是一定会存在一个默认的交换机
         消息一定是通过交换机传递给队列的
            channel.basicPublish("", "queue1", null, message.getBytes());

23.面试题:rabbitmq为什么是基于通道去处理的,而不是连接?
         连接是需要经过三次握手去连接,挺慢的,耗时很长,而且又开又关,会造成很大的性能开销

       channel的性能是非常高的,

24. 什么是AMQP协议?
      1. 生产者流转过程?
           建立连接; 开启通道; 发送消息; 释放资源

      2.消费者流转过程?
           建立连接; 开启通道; 准备接收消息; broker推送消息; 发送确认; 释放资源。

25.rabbitmq的核心组成部分?
         核心概念:
       Server:又称Broker ,接受客户端的连接,实现AMQP实体服务。 安装rabbitmq-server
    Connection:连接,应用程序与Broker的网络连接 TCP/IP/ 三次握手和四次挥手
    Channel:网络信道,几乎所有的操作都在Channel中进行,Channel是进行消息读写的通道,客户端可以建立对各Channel,每个Channel代表一个会话任务。
    Message :消息:服务与应用程序之间传送的数据,由Properties和body组成,Properties可是对消息进行修饰,比如消息的优先级,延迟等高级特性,Body则就是消息体的内容。
    Virtual Host 虚拟地址,用于进行逻辑隔离,最上层的消息路由,一个虚拟主机理由可以有若干个Exhange和Queueu,同一个虚拟主机里面不能有相同名字的Exchange
    Exchange:交换机,接受消息,根据路由键发送消息到绑定的队列。(==不具备消息存储的能力==)
    Bindings:Exchange和Queue之间的虚拟连接,binding中可以保护多个routing key.
    Routing key:是一个路由规则,虚拟机可以用它来确定如何路由一个特定消息。(相当于一个where条件)
    Queue:队列:也成为Message Queue,消息队列,保存消息并将它们转发给消费者。

 26.rabbitmq的运行流程?
       业务数据 --- 进行序列化(变成字节) --- 序列化之后的数据 ----  指定Exchange(交换机)和RountingKey(路由规则)---  消息
         ---- 发送到Broker(rabbitmq-server)中   ----  Consumer 订阅并接收消息  ---  反序列化 ---- 反序列化的数据  --- 业务数据处理

27.  RabbitMQ支持消息的模式?
         1.简单模式Simple  
          2.工作模式 Work:轮询模式    公平分发
          3. fanout发布订阅模式:只要发布者一发布信息,所有的订阅者都能够收到信息
          4.direct路由模式 :路由相当于一个过滤的条件,能够设置想要把信息发送给谁
          5.主题Topic模式:  模糊的routing-key的匹配模式,通过 #.order.* ,这些模糊字符来匹配  #:0,1.多个   *:至少有一个
           

 28. rabbitmq发送消息一定有一个交换机,如果没有指定交换机,会给一个默认的交换机(默认一般是direct路由模式)。
         发送消息一定是交换机去发送,而不是队列去发送

29.如果没有这个队列,或者没有这个交换机,我们需要自己从代码中去声明?
         #声明交换机
         channel.exchangeDeclare(exchangeName,exchangeType,true);
          #声明队列
          channel.queueDeclare("queue1",true,false,false)
          #绑定队列和交换机的关系
           channel.queueBind("queue",exchangName,"order");

30.Work模式-轮询模式?(按均分配)
        
    当有多个消费者时,我们的消息会被哪个消费者消费呢,我们又该如何均衡消费者消费信息的多少呢?
        主要有两种模式:
           1、轮询模式的分发:一个消费者一条,按均分配; (可以使用自动应答)
           2、公平分发:根据消费者的消费能力进行公平分发,处理快的处理的多,处理慢的处理的少;按劳分配;(一定使用手动应答)
             手动应答代码:   finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);

      work1和work2的消息处理能力不同,但是最后处理的消息条数相同,是“按均分配”。

 31. Work模式 - 公平分发?
        设置qos和手动应答
          finalChannel.basicQos(100);
            finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);

32.RabbitMQ使用场景?
       面试题:你在开发中怎么用到RabbitMQ的?
          我是2019年加入中地数码公司的,我刚加入的时候,我们公司并没有采用Rabbitmq,只是采用了
      一种单体架构,而单体结构的话,是把所有的业务都堆砌在一起,随着公司的业务的不断的发展和推进,
      我们公司的项目负责人把我们公司的项目进行了分裂,进行了一个分布式架构,进行了一个拆分,在拆分的
     过程中,我们考虑到一个问题,我们系统的什么模块和另外的一个模块,他们之间要进行一个沟通,这时候我们
      负责人就采用了消息队列,我们在选择的时候,就在思考用什么消息队列,后来就选择了rabbitmq,我自己
     使用rabbitmq的感觉的就是:最核心的一点是异步的,因为他是多线程的,分发的一个机制,可以让我们的
       网站的性能得到很大的提升,因为他的异步,让我们处理数据的能力变得更加的高效 和 那个 稳健;
    还有一个感受就是我们在开发的时候,我们会把这些服务进行一个分裂,分裂以后,就可以解耦
        rbbitmq配置到阿里云服务器上

        01,解耦、削峰、异步
        02, 高内聚,低耦合
        03. 流量削峰
        04、分布式事务的可靠消费和可靠生产
        05、索引、缓存、静态化处理的数据同步
        06、流量监控
        07、日志监控(ELK)
        08、下单、订单分发、抢票

33. springboot如何使用生产者 fanout模式?
         rbbitmq配置到阿里云服务器上

      #使用uuid
       String orderId =UUID.randomUUID().toString();
       #通过MQ来完成消息的分发
       #参数1:交换机   参数2:路由key/queue  参数3:消息内容
       String exchangeName = "fanout_order_exchange";
       String routingKey = "";
       rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);

     //绑定  将队列和交换机绑定, 并设置用于匹配键:TestDirectRouting
    @Bean
     public Binding binding1() {
        return BindingBuilder.bind(weixinQueue()).to(fanoutOrderExchange()).with("");
    }

34.  direct消费者接收的话?使用@RabbitListener
        代码:
          @Component
          @RabbitListener (queues = {"sms.direct.queue"})
          public class DirectSMSConsumer{  }

35.面试题?
      在开发过程中,我们这些绑定关系,就是队列的声明,交换机的声明,是配置在
       生产者这边好一点,还是配置在消费者这边好一点?
         1.其实在生产者这边声明也可以,在消费者这边声明也可以,或者俩边都定义也ok,甚至可以用手动的方式,
         在web页面上来绑定关系,但是最好还是用程序去定义;    我们做的时候,是在消费者这边去声明的,我们在
         启动过程中,我们的消费者,如果你的队列还没有去声明,那么接下来,他肯定会出错, 消费者是直接和我们的
        队列打交道的一个地方。


36.   topic模式 消费者?
 // bindings其实就是用来确定队列和交换机绑定关系
@RabbitListener(bindings =@QueueBinding(
        // email.fanout.queue 是队列名字,这个名字你可以自定随便定义。
        value = @Queue(value = "email.topic.queue",autoDelete = "false"),
        // order.topic 交换机的名字 必须和生产者保持一致
        exchange = @Exchange(value = "topic_order_exchange",
                // 这里是确定的rabbitmq模式是:topic 是以广播模式 、 发布订阅模式
                type = ExchangeTypes.TOPIC)
))
      

37.   过期时间TTL?
     RabbitMQ可以对 消息 和 队列 设置TTL。目前有两种方法可以设置。
        第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。
       第二种方法是对消息进行单独设置,每条消息TTL可以不同。

如果上述两种方法同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,就称为dead message被投递到死信队列, 消费者将无法再收到该消息。

    // 6: 准备发送消息的内容
            String message = "你好,学相伴!!!";
            Map<String, Object> headers = new HashMap<String, Object>();
            headers.put("x", "1");
            headers.put("y", "1");
            AMQP.BasicProperties basicProperties = new AMQP.BasicProperties().builder()
                    .deliveryMode(2) // 传送方式
                    .priority(1)
                    .contentEncoding("UTF-8") // 编码方式
                    .expiration("5000") // 过期时间
                    .headers(headers).build(); //自定义属性

   expiration 字段以微秒为单位表示 TTL 值。且与 x-message-ttl 具有相同的约束条件。因为 expiration 字段必须为字符串类型,broker 将只会接受以字符串形式表达的数字。
   当同时指定了 queue 和 message 的 TTL 值,则两者中较小的那个才会起作用。


38. 死信队列?
        当消息在一个队列中变成死信(dead message)之后,就是到了过期时间,它就被重新发送到另一个交换机中,这个交换机就是DLX ,绑定DLX的队列就称之为死信队列。

      消息变成死信,可能是由于以下的原因:
        消息被拒绝
         消息过期
        队列达到最大长度
   
  代码:过期队列和死信队列产生关联
     @Bean
     public Queue directttlQueue(){
             Map<String,Object> args = new HashMap<>();
             args.put("x-message-ttl",5000);
             args.put("x-dead-letter-exchange","dead_driect_exchange");
             args.put("x-dead-lettet-rounting-key","dead");
             return new Queue("ttl.direct.queue",true,false,false);
     }

 队列一旦被创建,想要去修改和添加参数,他是不会去覆盖,也不会去进行一个变更,而是会报错。
 可以重新去取一个名字,而不是去删除

39.  内存磁盘和监控?
           1. RabbitMQ的内存控制:使用命令去控制:
               rabbitmqctl set_vm_memory_high_watermark 0.4

          2.RabbitMQ的磁盘预警:  使用命令控制:
              rabbitmqctl set_disk_free_limit  3.0

          3.RabbitMQ的内存换页?
               比如有1000MB内存,当内存的使用率达到了400MB,已经达到了极限,但是因为配置的换页内存0.5,这个时候会在达到极限400mb之前,会把内存中的200MB进行转移到磁盘中。从而达到稳健的运行。
              vm_memory_high_watermark.relative = 0.4

40. RibbitMQ持久化?
      持久化:将内存里面的消息队列,同步到磁盘中去。
        RabbitMQ的持久化队列分为:
           1:队列持久化
            2:消息持久化
            3:交换机持久化
          不论是持久化的消息还是非持久化的消息都可以写入到磁盘中,只不过非持久的是等内存不足的情况下才会被写入到磁盘中。

      队列持久化:
       // 参数1:名字  
       // 参数2:是否持久化,
       // 参数3:独du占的queue,
       // 参数4:不使用时是否自动删除,
       // 参数5:其他参数
      channel.queueDeclare(queueName,true,false,false,null);

       消息持久化:
          // 参数1:交换机的名字
          // 参数2:队列或者路由key
         // 参数3:是否进行消息持久化
         // 参数4:发送消息的内容
       channel.basicPublish(exchangeName, routingKey1, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());

      交换机持久化:
          // 参数1:交换机的名字
          // 参数2:交换机的类型,topic/direct/fanout/headers
         // 参数3:是否持久化
       channel.exchangeDeclare(exchangeName,exchangeType,true);

41. 集群的节点?
        1.集群的各个节点内部的信息都是同步的,不管是交换机还是队列
        2。如果从节点挂了,是没有关系的,但是不能挂主节点,如果主节点挂掉,从节点是无法启动的

      Tips:
        如果采用多机部署方式,需读取其中一个节点的cookie, 并复制到其他节点(节点之间通过cookie确定相互是否可通信)。cookie存放在/var/lib/rabbitmq/.erlang.cookie。

42.  分布式事务?
          事务控制的代码:
              @Transactional(rollbackFor = Exception.class)  //订单创建整个方法添加事务  acid

     1.基于MQ解决的分布式事务问题? 俩个服务之间,保持数据一致性(订单服务,配送中心)
          1.基于MQ的分布式事务消息的可靠生产问题-定时重发?
                    (1)设置一个定时器,隔一段时间,定时的发送
                (1)在同一个事务中,增加一个冗余表的记录订单数据每条数据和是否发送成功的状态
                   (2)然后利用rabbitmq提供的publisher/confirm机制开启确认机制后,如果消息正常发送到
                       MQ中就会获得回执信息,然后把状态改为已发送状态。


43.消息确认机制的配置?
       publisher-confirm-type: correlated

44. 面试题:
        如果消费者在消费过程中出现异常,rabbitmq会出现什么样的问题?
           会出现死循环问题,解决死循环问题?或者问解决消息重试的几种方案?
               1.控制重发的次数
               2.try+catch+手动ack
               3. try+catch+手动ack + 死信队列处理  + 人工干预

     
45. RabbitMQ 集群监控?
       我们一定是把消息的可靠性放在第一位的,
 
        我们公司用的tracing日志监控             
        tracing日志监控  :Trace是Rabbitmq用于记录每一次发送的消息, 是可以通过插件形式提供可视化界面的,  
          Trace启动后会自动创建系统Exchange:amq.rabbitmq.trace ,每个队列会自动绑定该Exchange,绑定后发送到队列的消息都会记录到Trace日志。


46. 面试题: Rabbitmq 为什么需要信道,为什么不是TCP直接通信?
        1、TCP的创建和销毁,开销大,创建要三次握手,销毁要4次分手。

        2、如果不用信道,那应用程序就会TCP连接到Rabbit服务器,高峰时每秒成千上万连接就会造成资源的巨大浪费,而且==底层操作系统每秒处理tcp连接数也是有限制的,==必定造成性能瓶颈。


 47.面试题: queue队列到底在消费者创建还是生产者创建?   
      1: 一般建议是在rabbitmq操作面板创建。这是一种稳妥的做法。
      2:按照常理来说,确实应该消费者这边创建是最好,消息的消费是在这边。这样你承受一个后果,可能我生产在生产消息可能会丢失消息。
      3:在生产者创建队列也是可以,这样稳妥的方法,消息是不会出现丢失。
      4:如果你生产者和消费都创建的队列,谁先启动谁先创建,后面启动就覆盖前面的


48. 面试题: 如何保证 RabbitMQ 高可用?
         我们公司搭建的RabbitMQ集群,搭建了3台,数量在500万内。
 

49. 面试题:如何保证 RabbitMQ 消息不被重复消费?
        先说为什么会重复消费:正常情况下,消费者在消费消息的时候,消费完毕 后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将 该消息从消息队列中删除。
       但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列 不知道自己已经消费过该消息了,再次将消息分发给其他的消费者。
    
      这个其实就是保证消息的幂等性?
          比如:在写入消息队列的数据做唯一标示,消费消息时,根据唯一标识判断 是否消费过。


50. 面试题: 如何保证 RabbitMQ 消息可靠传输?
          1.生产者丢失消息?
               confirm 模式:一旦 channel 进入 confirm 模式,所有在该信道上发布的消 息都将会被指派一个唯一的 ID(从 1 开始),
               一旦消息被投递到所有匹配的队 列之后。RabbitMQ 就会发送一个 ACK 给生产者(包含消息的唯一 ID),这就 使得生产者知道消息已经正确到达目的队列了.
                如果 rabbitMQ 没能处理该消息, 则会发送一个 Nack 消息给你,你可以进行重试操作。
          2.消息队列丢数据?
               消息持久化。处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。
                 1. 将 queue 的持久化标识 durable 设置为 true,则代表是一个持久的队列。
                 2. 发送消息的时候将 deliveryMode=2。 这样设置以后,即使 rabbitMQ 挂了,重启后也能恢复数据。
          3.消费者丢失消息?
                  消费者丢数据一般是因为采用了自动确认消息模式,改为手动确认消息即 可!消费者在收到消息之后,处理消息之前,会自动回复 RabbitMQ 已收到消 息。
                     如果这时处理消息失败,就会丢失该消息。 解决方案:处理消息成功后,手动回复确认消息。


51. 面试题:如何保证 RabbitMQ 消息的顺序性?
          单线程消费保证消息的顺序性。对消息进行编号,消费者处理消息是根据编号处理消息。


52. 面试题:RabbitMQ 消息堆积如何处理?
         1. 增加消费者的处理能力(例如优化代码),或减少发布频率。
          2. 考虑使用队列最大长度限制。
           3. 给消息设置年龄,超时就丢弃。
           5. 建立新的 queue,消费者同时订阅新旧 queue,采用订阅模式。

53. 面试题: RabbitMQ 消息丢失解决方案?
          消息持久化 Exchange 设置持久化:durable:true。
           Queue 设置持久化;Message 持久化发送。
          ACK 确认机制 消息发送确认。 消息接收手动确认 ACK。


54.面试题: RabbitMQ 宕机了怎么处理?
         RabbitMQ 提供了持久化的机制,将内存中的消息持久化到硬盘上,即使重 启 RabbitMQ,消息也不会丢失。
           持久化标识 durable 设置为 true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值