• 消息队列经典


    1. 什么是消息队列

    你可以把消息队列理解为一个使用队列来通信的组件。它的本质,就是个转发器,包含发消息、存消息、消费消息的过程。最简单的消息队列模型如下:

    2. 消息队列有哪些使用场景。

    有时候面试官会换个角度问你,为什么使用消息队列。你可以回答以下这几点:

    1. 应用解耦
    2. 流量削峰
    3. 异步处理
    4. 消息通讯
    5. 远程调用

    3. 消息队列如何解决消息丢失问题?

    一个消息从生产者产生,到被消费者消费,主要经过这3个过程:

    因此如何保证MQ不丢失消息,可以从这三个阶段阐述:

    • 生产者保证不丢消息
    • 存储端不丢消息
    • 消费者不丢消息
    • 3.1 生产者保证不丢消息

    • 确保生产的消息能到达存储端

      如果是RocketMQ消息中间件,Producer生产者提供了三种发送消息的方式,分别是:

      • 同步发送
      • 异步发送
      • 单向发送

      生产者要想发消息时保证消息不丢失,可以:

      • 采用同步方式发送,send消息方法返回成功状态,就表示消息正常到达了存储端Broker。
      • 如果send消息异常或者返回非成功状态,可以重试
      • 可以使用事务消息,RocketMQ的事务消息机制就是为了保证零丢失来设计的
    • 3.2 存储端不丢消息

      确保消息持久化到磁盘。大家很容易想到就是刷盘机制

      刷盘机制分同步刷盘和异步刷盘

      • 生产者消息发过来时,只有持久化到磁盘,RocketMQ的存储端Broker才返回一个成功的ACK响应,这就是同步刷盘。它保证消息不丢失,但是影响了性能。
      • 异步刷盘的话,只要消息写入PageCache缓存,就返回一个成功的ACK响应。这样提高了MQ的性能,但是如果这时候机器断电了,就会丢失消息。

      Broker一般是集群部署的,有master主节点和slave从节点。消息到Broker存储端,只有主节点和从节点都写入成功,才反馈成功的ack给生产者。这就是同步复制,它保证了消息不丢失,但是降低了系统的吞吐量。与之对应的就是异步复制,只要消息写入主节点成功,就返回成功的ack,它速度快,但是会有性能问题。

    • 3.3 消费阶段不丢消息

      消费者执行完业务逻辑,再反馈Broker说消费成功,这样才可以保证消费阶段不丢消息。

    5.消息队列有可能发生重复消费,如何避免,如何做到幂等

    消息队列是可能发生重复消费的。

    • 生产端为了保证消息的可靠性,它可能往MQ服务器重复发送消息,直到拿到成功的ACK。
    • 再然后就是消费端,消费端消费消息一般是这个流程:拉取消息、业务逻辑处理、提交消费位移。假设业务逻辑处理完,事务提交了,但是需要更新消费位移时,消费者却挂了,这时候另一个消费者就会拉到重复消息了。

    简单来说,就是搞个本地表,带唯一业务标记的,利用主键或者唯一性索引,每次处理业务,先校验一下就好啦。又或者用redis缓存下业务标记,每次看下是否处理过了。

    6. 如何处理消息队列的消息积压问题

    可以确认是不是可以优为批量处理消息。如果还是慢,我们可以考虑水平扩容,增加Topic的队列数,和消费组机器的数量,提升整体消费能力。

  • 相关阅读:
    map,forEach,some,every,filter条件过滤的区别
    dangerouslySetInnerHTML空格不换行解决方案
    react项目里link语法报错Dangerous property 'dangerouslySetInnerHTML'
    如何判断两个数组是否相等相等
    react hooks的缺点(针对状态不同步和没有生命周期)
    面试聊啥
    Win10 PIN码是什么?如何设置?
    三个环形图(万一是n个呢)
    Chrome 离线加装扩展的新方法
    java安装
  • 原文地址:https://www.cnblogs.com/KL2016/p/16116945.html
Copyright © 2020-2023  润新知