Mq面试题

文章目录

    • 1、什么是消息队列?
    • 2、消息队列有哪些使用场景?(为什么使用消息队列)
      • 2.1 应用解耦
      • 2.2 流量削峰
      • 2.3 异步处理
      • 2.4 消息通讯
      • 2.5 远程调用
    • 3、消息队列如何解决消息丢失问题?
      • 3.1 生产者保证消息不丢失
      • 3.2 存储段不丢消息
      • 3.3 消费者不丢消息
    • 4、消息队列如何保证消息的顺序性?
      • 4.1 单机:
      • 4.2 集群:
        • 4.2.1 生产者有序消费
        • 4.2.2 消费者有序消费
    • 5、如何避免消息重复消费?
      • 5.1 提高消费端的处理性能,避免触发Balance
      • 5.2 使用ConsumerRebalanceListener,再均衡监听器
      • 5.3 使用消息幂等性
    • 6、如何解决幂等性问题?
      • 6.1 概念
      • 6.2 问题
      • 6.3 如何解决?
    • 7、如何处理消息队列消息积压问题?
    • 8、MQ技术选型
    • 9、如何保证数据一致性,事务消息如何实现?
    • 10、RabbitMQ的消息可靠传输如何保证?
    • 11、RabbitMQ的消息如何实现路由?

1、什么是消息队列?

Message Queue 简称 MQ,是一种应用间的通信方式,由生产者Producer、代理Broker、消费者Consumer三者组成。

场景

  1. 异步,实时性要求不严格的场景,注册发送验证码、下单通知、发送优惠券等。不需要等待消息服务返回结果。
  2. 应用解耦,将相关但耦合度不高的系统联系起来。解决了各个系统可以采用不同的架构、语言来实现,大大增加系统的灵活性。
  3. 流量削峰,应用在大流量入口且短时间内业务需求处理不完的服务中心,为权衡高可用,将大量并行业务发送到MQ,起到大流量缓冲的作用。

类型:ActiveMQ、RabbitMQ、Kafka、RocketMQ

中小型公司、低吞吐量一般用ActiveMQ、RabbitMQ。

大数据高吞吐量的大型公司一般选用用Kafka和RocketMQ。

2、消息队列有哪些使用场景?(为什么使用消息队列)

2.1 应用解耦

  1. 将相关但耦合度不高的系统联系起来。解决了各个系统可以采用不同的架构、语言来实现,大大增加系统的灵活性。
  2. 扩充下游系统时不需要做大的调整。

2.2 流量削峰

场景特点:应用在大流量入口且短时间内业务需求处理不完的服务中心

比如做秒杀,需要避免流量暴涨打垮应用的风险。假设系统每秒最多处理2k个请求,但实际每秒有5k个请求,此时引入消息队列,每秒从队列中拉取2k个请求处理就可以了。

消息积压

  • 秒杀活动不可能每时每刻大请求量,高峰期过去,积压请求可以慢慢处理。
  • 队列长度超过最大数量,可以直接抛弃用户请求,走兜底业务

2.3 异步处理

将按顺序执行的业务,同步执行,大大减少响应速度。

2.4 消息通讯

内置了高效的通讯机制,可以实现点对点消息队列、聊天室等。

2.5 远程调用

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

生产者产生消息-》Broker代理存储消息-》消费者消费消息

3.1 生产者保证消息不丢失

如果使用RocketMQ消息中间件,生产者提供了三种发送方式:同步、异步、单向

  • 采用同步发送,send消息返回成功状态,则表示成功存储
  • send消息异常或返回非成功状态,可以重试
  • 可以使用事务消息,RocketMQ事务消息机制就是为了保证零丢失设计的

3.2 存储段不丢消息

刷盘机制

生产者发送消息,只有持久化到磁盘,RocketMQ存储端才会返回一个成功ACK响应。但影响性能。

异步刷盘

只要消息写入PageCache缓存,就返回一个成功ACK响应。提高了性能,但一单及其断电,就会丢失消息。

Broker一般集群部署,有master主节点和slave从节点。

同步复制:主节点和从节点都收到消息,才返回成功ACK,保证了消息不丢失,但降低性能。

异步复制:只要消息写入主节点,就返回成功ACK,速度快,但会有丢失问题。

3.3 消费者不丢消息

消费者执行完业务逻辑,在反馈给Broker消费成功。

4、消息队列如何保证消息的顺序性?

4.1 单机:

发送至同一个服务的MQ上,发送至同一个服务的消费者,且等到M1消费端ACK成功后,M2再发送。

4.2 集群:

生产者有序存储、消费者有序消费。

4.2.1 生产者有序消费

普通发送消息的模式下,生产者采用轮询的方式均匀发送至不同队列中,被不同的消费者消费。此时无法使用队列有序特性保证有序性。

解决方案:投放消息支持自定义投放策略,顺序消息必须使用同步发送的方式,才能保证发送有序。

实现一个**MessageQueueSelector接口**,使用Hash取模法来保证同一个订单在同一个队列中就行了

即通过订单ID%队列数量得到该ID的订单所投放的队列在队列列表中的索引,然后该订单的所有消息都会被投放到这个队列中。

4.2.2 消费者有序消费

RockerMQ的MessageListener回调函数提供了两种消费模式,有序消费模式MessageListenerOrderly和并发消费模式MessageListenerConcurrently。

在消费的时候,还需要保证消费者注册MessageListenerOrderly类型的回调接口实现顺序消费,如果消费者采用Concurrently并行消费,则仍然不能保证消息消费顺序。

实际上,每一个消费者的的消费端都是采用线程池实现多线程消费的模式,即消费端是多线程消费。虽然MessageListenerOrderly被称为有序消费模式,但是仍然是使用的线程池去消费消息。

MessageListenerConcurrently是拉取到新消息之后就提交到线程池去消费,而MessageListenerOrderly则是通过加分布式锁和本地锁保证同时只有一条线程去消费一个队列上的数据。

messageQueue的本地synchronized锁

  1. 执行消费任务的开头获取本地锁对象objLock,通过synchronized实现锁定。
  2. 锁对象存储在MessageQueueLock.mqLockTable属性中,结构为ConcurrentMap<MessageQueue, Object>,一个messageQueue对应一个锁。
  3. 这个锁保证同一时刻对于同一个队列只有一个线程去消费他。

ProcessQueue的本地consumeLock

执行真正的消费之前,会获取ProcessQueue的本地consumeLock,这个本地锁是一个ReentrantLock。

作用:防止在消费过程中,该消息队列因负载均衡而被分配给其他客户端,导致两个客户端重复消费。

5、如何避免消息重复消费?

生产端为保证消息可靠性,可能想MQ重复发送消息,直到拿到成功的ACK。

消费端流程:拉取消息-》业务逻辑执行-》提交消费位移。

假设更新位移时,消费者挂了,这时另一个消费者就会拉取到重复的消息。

解决方案

5.1 提高消费端的处理性能,避免触发Balance

  • 多线程处理消息,缩短单个消息消费时长。
  • 调整消息处理的超时时间。
  • 减少一次性从Broker上拉取数据的条数。

5.2 使用ConsumerRebalanceListener,再均衡监听器

设定发生再均衡动作前后的一些准备工作和收尾工作。

5.3 使用消息幂等性

  • 开启KafKa的幂等性功能
  • 将消息生成md5,带唯一业务标记,保存到Mysql或Redis中,在处理消息之前先查Mysql或Redis,进行判断是否已消费。

6、如何解决幂等性问题?

6.1 概念

一个方法无论被多少次重复执行,所期望的结果和第一次执行所期望的结果保持一致。

6.2 问题

  • 用户重复提交、恶意攻击
  • 分布式系统中,为避免数据丢失,采用的超时重试机制

6.3 如何解决?

本质:保证接口的执行结果只影响一次,后续再次调用,不能对数据产生影响。

  1. 使用数据库唯一约束实现。
  2. 使用Redis提供的setNX指令
  3. 使用状态机实现,即一条数据的完整运行状态的转换流程,状态只会向前变更

7、如何处理消息队列消息积压问题?

起因:消费速度原小于生产速度

临时解决:紧急扩容,先保证消息都消费完。

  1. 修复consumer消费者问题,确保恢复消费速度,然后将现有consumer都停掉。
  2. 新建一个topic,partition,临时建立好原先10倍的queue数量。
  3. 写一个临时分发数据的consumer程序,部署上去消费积压的数据,消费之后不做耗时处理,直接轮询写入临时创建好的10倍数量的queue中。
  4. 临时征用10倍数量的机器部署consumer,每一批consumer消费一个临时queue数量。相当于临时将queue资源和consumer资源扩大10倍,10倍速度消费。
  5. 快速消费积压数据后,恢复原先部署的程序。

8、MQ技术选型

指标KafkaRocketMQRabbitMQ
单机吞吐量17.3w/s11.6w/s2.6w/s(消息做持久化)
开发语言Scala/JavaJavaErlang
维护ApacheAlibabaSpring
订阅形式基于topic,进行正则匹配基于topic、messageTag,根据类型和属性正则匹配支持direct、topic、Headers、fanout四种模式
持久化支持大量堆积支持大量堆积支持少量堆积
顺序消息支持支持不支持
集群方式天然Leader-Slave,无状态集群,每台服务器既是Master也是Slave常用“多对Master-Slave”,开源版需要手动切换从节点变主节点支持简单集群,“复制模式”,对高级集群支持不好
性能稳定性较差一般
  • 大数据领域实时计算、日志采集等,用Kafka为业内标准
  • RocketMQ,阿里出品
  • RabbitMQ开源,稳定支持、活跃度高,但不是Java开发

9、如何保证数据一致性,事务消息如何实现?

  1. 生产者发送消息到MQ服务器
  2. MQ收到消息后,持久化到存储系统,状态为代发送
  3. MQ服务器返回ACK确认到生产者,此时还不触发推送事件
  4. 生产者执行本地事务
  5. 本地事务执行成功,提交结果到MQ服务器,执行失败发送rollback
  6. 正常提交,MQ更新消息状态为可送达,rollback回滚则删除消息
  7. 如果消息更新为可送达,则MQ服务器push消息给消费者,消费完成就回ACK。
  8. 如果MQ服务器长时间没有收到生产者的commit或rollback,会反查生产者,根据查询结果执行最终状态

10、RabbitMQ的消息可靠传输如何保证?

丢失的三种情况

  • 生产者发送消息到MQ 服务的过程中丢失
  • MQ服务收到消息后,在持久化之前宕机,导致数据丢失
  • 消费端收到消息还未处理

对于生产者:生产者发送之后,MQ提供了一个消息确认机制,客户端根据消息的处理结果决定是否需要重新发送。

MQ 服务端:开启消息持久化机制,存入磁盘。

  • 创建Queue设置持久化
  • 发送消息的时候,将消息投递模式设置为持久化投递。

消费端:将消息的自动确认机制修改为手动确认,只会手动用消息确认方法才表示消息已被签收。

11、RabbitMQ的消息如何实现路由?

本质:一个基于AMQP协议实现的分布式消息中间件。

AMQP工作机制

  • 生产者将消息发送到RabbitMQ Broker上的Exchange交换机上。
  • Exchange交换机把收到的消息根据路由规则发给绑定的Queue队列。
  • 再把消息投递给订阅了这个队列的消费者,完成消息的异步通讯。

Exchange :消息交换机,定义了消息路由的规则,规定消息与队列的关系。

Queue:消息的载体,每个消息可以根据路由规则到一个或多个队列中。

RoutingKey:路由键,发送消息时声明,Exchange拿到路由键,根据它和路由表里面的BindingKey进行匹配。

在RabbitMQ中,有三种类型的Exchange:direct ,fanout和topic。

direct:完整匹配,是Routing key和Binding Key完全一致,点对点发送。

fanout:广播机制,不急于路由键匹配,将消息广播给绑定到当前交换机上的所有队列。

topic:正则表达式匹配,根据Routing key使用正则表达式进行匹配,发送消息给符合规则的Queue。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/112553.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

购药不烦恼:线上购药小程序的快捷方式

在这个数字化时代&#xff0c;线上购药小程序的快捷方式正在改变着我们购药的方式。本文将介绍如何通过使用Python和Flask框架创建一个简单的线上购药小程序的原型&#xff0c;为用户提供购药的便利和快捷体验。 安装和设置 首先&#xff0c;确保你已经安装了Python和Flask。…

AUTOSAR AP 硬核知识点梳理(2)— 架构详解

一 AUTOSAR 平台逻辑体系结构 图示逻辑体系结构描述了平台是如何组成的,有哪些模块,模块之间的接口是如何工作的。 经典平台具有分层的软件体系结构。定义明确的抽象层,每个抽象层都有精确定义的角色和接口。 对于应用程序,我们需要考虑使用的软件组件,希望它们是可重用的…

墨迹天气商业版UTF-8模板,Discuz3.4灰白色风格(带教程)

1.版本支持&#xff1a;Discuzx3.4版本&#xff0c;Discuzx3.3版本&#xff0c;DiscuzX3.2版本。包括网站首页&#xff0c;论坛首页&#xff0c;论坛列表页&#xff0c;论坛内容页&#xff0c;论坛瀑布流,资讯列表页(支持多个)&#xff0c;产品列表页(支持多个)&#xff0c;关于…

Discourse 的用户快速找到管理员账号

在 Discourse 的社区中可能有多个用户账号为管理员或者有特殊权限的账号。 这个账号在 Discourse 的用户&#xff0c;然后 Staff 中可以快速找到。 作为管理员&#xff0c;有时候需要检查下你的 Discourse 是不是没有进行管理&#xff0c;有多长时间没有登录了。 ​编辑 这个…

CloudCompare 二次开发(18)——法线空间采样

目录 一、概述二、代码集成三、结果展示一、概述 使用CloudCompare与PCL的混合编程实现点云法线空间采样。法线空间采样的具体计算原理见:PCL 法线空间采样。 二、代码集成 1、mainwindow.h文件public中添加: void doActionNormalSpaceSample(); // 法线空间采样2、mainwi…

微信小程序之首页-后台交互及WXS的使用

目录 前言 一. 前后台数据交互及封装request 1.准备后台 1.1 配置数据源 1.2 部分后台获取数据方法编写 2.准备前端 2.1封装Request 2.2 前端JS方法编写 2.3 前端页面展示index.wxml 二.WXS的使用 1.简介 2.WXS优化OA系统 2.1 使用及定义 2.2 导入要使用的项目 2.…

如何理解TCP/IP协议?

一、是什么 TCP/IP&#xff0c;传输控制协议/网际协议&#xff0c;是指能够在多个不同网络间实现信息传输的协议簇 TCP&#xff08;传输控制协议&#xff09; 一种面向连接的、可靠的、基于字节流的传输层通信协议 IP&#xff08;网际协议&#xff09; 用于封包交换数据网…

分类预测 | MATLAB实现基于BiGRU-AdaBoost双向门控循环单元结合AdaBoost多输入分类预测

分类预测 | MATLAB实现基于BiGRU-AdaBoost双向门控循环单元结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于BiGRU-AdaBoost双向门控循环单元结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于BiGRU-AdaBoos…

nodejs+vue 校园通勤车-计算机毕业设计

在此情况下开发一款校园通勤车可视化系统小程序&#xff0c;于是乎变得非常合乎时宜。 经过网上调查和搜集数据,我们可以发现校园通勤车可视化管理方面的小程序在并不是相当普及,同时在校园通勤车可视化管理方面的可以有许多改进。目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪…

LiveQing视频点播流媒体RTMP推流服务功能-支持视频点播分屏大屏展示视频轮巡分组播放RMP推流直播大屏展示

LiveQing支持视频点播分屏大屏展示视频轮播分组播放RMP推流直播大屏展示 1、分屏展示2、轮巡播放3、RTMP推流视频直播和点播流媒体服务 1、分屏展示 LiveQing支持将视频点播、鉴权直播&#xff0c;拉转直播视频流&#xff0c;进行分屏播放。 2、轮巡播放 3、RTMP推流视频直播和…

短视频矩阵系统源码---php搭建

一、智能剪辑、矩阵分发、无人直播、爆款文案于一体独立应用开发 抖去推----主要针对本地生活的----移动端(小程序软件系统&#xff0c;目前是全国源头独立开发)&#xff0c;开发功能大拆解分享&#xff0c;功能大拆解&#xff1a; &#xff08;1&#xff09;数据概览&#x…

SpringCloud 微服务全栈体系(二)

第三章 Eureka 注册中心 假如我们的服务提供者 user-service 部署了多个实例&#xff0c;如图&#xff1a; 思考几个问题&#xff1a; order-service 在发起远程调用的时候&#xff0c;该如何得知 user-service 实例的 ip 地址和端口&#xff1f;有多个 user-service 实例地址…

#力扣:2769. 找出最大的可达成数字@FDDLC

2769. 找出最大的可达成数字 - 力扣&#xff08;LeetCode&#xff09; 一、Java class Solution {public int theMaximumAchievableX(int num, int t) {return num 2*t;} }

学生学徒作品分享——金融大模型-房屋租金价格影响因素分析与预测

金融大模型-房屋租金价格影响因素分析与预测项目背景 广州作为中国最发达的城市之一&#xff0c;每年都吸引大量务工人员前来就业&#xff0c;而租房是他们需要解决的最大问题之一&#xff0c;各地区租房需求日益增长。在租房过程&#xff0c;价格、交通是重要的考虑因素&a…

Kotlin类的定义、构造函数、封装、继承和多态

Kotlin是一门面向对象的编程语言&#xff0c;它支持类的定义、构造函数、封装、继承和多态&#xff0c;这些是面向对象编程的核心概念。在下面的示例中&#xff0c;我们将通过代码来说明这些概念。 类的定义和成员访问 在Kotlin中&#xff0c;使用关键字class来定义一个类。类…

使用 Rust 开发:以太坊与 Layer2 生态建设新趋势

Rust 是一种系统编程语言&#xff0c;以其出色的性能、内存安全和并发性而闻名&#xff0c;在区块链和 Web3 中广泛应用&#xff0c;大多数编程语言和开发框架都以 Rust 为核心&#xff0c;如 Polkadot、Solana、NEAR、Elrond&#xff08;现名 MultiversX&#xff09;、Hyperle…

android 指针动画转动

记录一种简单动画 效果图&#xff1a; 都是直接使用图片资源FrameLayout布局实现&#xff0c;布局如下&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"…

【JavaEE】Java多线程编程案例 -- 多线程篇(3)

Java多线程编程案例 1. 单例模式1.1 代码的简单实现1.2 懒汉模式的线程安全代码 2. 阻塞队列2.1 阻塞队列的概念2.2 使用库中的BlockingDeque2.3 模拟实现阻塞队列2.4 生产者消费者模型 3. 定时器3.1 概念3.2 使用库的定时器 - Timer类3.3 模拟实现定时器 4. 线程池4.1 概念4.2…

面向对象设计原则之依赖倒置原则

目录 定义原始定义进一步的理解 作用实现方法代码示例 面向对象设计原则之开-闭原则 面向对象设计原则之里式替换原则 面向对象设计原则之依赖倒置原则 面向对象设计原则之单一职责原则 定义 依赖倒置原则&#xff08;Dependence Inversion Principle&#xff09;&#xff0c…

互联网Java工程师面试题·Java 总结篇·第十一弹

目录 90、简述一下你了解的设计模式。 91、用 Java 写一个单例类。 92、什么是 UML&#xff1f; 93、UML 中有哪些常用的图&#xff1f; 94、用 Java 写一个冒泡排序。 95、用 Java 写一个折半查找。 90、简述一下你了解的设计模式。 所谓设计模式&#xff0c;就是一套被…