Java ZooKeeper-RocketMQ 面试题

Java ZooKeeper-RocketMQ 面试题

  • 前言
  • 1、谈谈你对ZooKeeper的理解 ?
  • 2、Zookeeper的工作原理(Zab协议)
  • 3、谈谈你对分布式锁的理解,以及分布式锁的实现?
  • 4、 zookeeper 是如何保证事务的顺序一致性的?
  • 5、 zookeeper主从同步机制:
  • 6、分布式集群中为什么会有 Master?
  • 7、 zk 节点宕机如何处理?
  • 8、说几个 zookeeper 常用的命令?
  • 9、ZK 如何投票实现Leader选举?
  • MQ中间件
  • 10、什么是 RocketMq?
  • 11、什么是消息队列?
  • 12、RocketMq的路由类型和发送消息的方式?
  • 13、死信消息的生命周期?
  • 14、如何保证消息的顺序性?
  • 15、如何防止消息丢失?
  • 16、如何保证消息不被重复消费?
  • 17、MQ处理消息失败了怎么办?
  • 18、消息基于什么传输?
  • 19、RocketMQ 底层原理?
  • 20、RocketMQ为什么速度快, 吞吐量?
  • 21、什么是零拷贝?
  • 22、死信队列?
  • 总结


前言

最新的 Java 面试题,技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linux…等等,会持续更新。

如果对老铁有帮助,帮忙免费点个赞,谢谢你的发财手!

1、谈谈你对ZooKeeper的理解 ?

ZooKeeper 是一个开源的分布式协调服务,为分布式系统提高了一系列的服务,提供的服务包括了:服务注册与订阅、统一命名服务、集群管理、分布式锁和分布式通知等。
Zookeeper提供了三个核心功能,分别是:文件系统、监听机制和集群管理

  • 1、文件系统
    Zookeeper存储数据的结构,类似于一个文件系统,每个节点(znode)都是类似于K-V的结构,每个节点的名字相当于key,每个节点保存的数据,相当于value。
  • 2、监听机制
    客户端先向ZooKeeper服务端的某个节点注册一个 Watcher 监听,当监听的数据状态发生变化时,服务端会向指定客户端发送一个事件通知,客户端收到事件以后,调用对应的回调方法,完成事件变更的通知。
  • 3、集群管理
    Zookeeper提供了CP的模型,来保证集群中的每个节点的数据一致性。
    zookeeper本身是一个集群结构,它有3种角色:
    leader领导者:处理所有的事务请求(写请求),也可以处理读请求,集群中只有一个leader;
    follower追随者:只能处理读请求,参与leader选举
    observer观察者:只能处理读请求,不参与leader选举,作用是为了提升集群的读性能

2、Zookeeper的工作原理(Zab协议)

  • Zookeeper的工作原理核心是原子广播机制,这个机制保证了各个节点之间的数据一致性,实现这个机制的协议叫做Zab协议。
    Zab协议有两种模式,分别是恢复模式(选主)和广播模式(同步),当服务启动或者 Leader 服务器宕机,Zab就进入了恢复模式,此时不对外提供服务。
  • 首先选举出新的 Leader 服务器,然后与其他的Follower 服务器进行数据同步,当集群中超过半数机器完成数据同步之后,退出恢复模式进入广播模式,然后就可以接收客户端的事务请求了。

3、谈谈你对分布式锁的理解,以及分布式锁的实现?

  • 分布式锁,是一种跨进程的跨机器节点的互斥锁,它可以保证同一时刻只能有一个线程去访问共享资源。
    目前实现分布式锁最常用的中间件是 Redis 和 Zookeeper:
  • Redis:利用它提供的 SETNX 命令,如果设置key返回1,说明获取锁成功,返回0获取锁失败。然后还可以通过 EX参数来设置key的过期时间,从而避免死锁问题。
    但也可能存在一些极端情况,比如锁过期了,但是业务逻辑还没处理完。这种极端情况可以使用Redisson 客户端来实现,Redisson 中有一个 watchdog 的机制,翻译过来就是看门狗,它是基于Netty下面的一个时间轮的实现类来实现。(getLock、lock、unlock)
  • Zookeeper:利用它提供的有序节点,当线程创建节点后,如果该节点是当前目录下所有节点序号最小的节点,则认为获取锁成功。如果不是最小的节点,则对该节点序号的前一个节点添加一个监听事件,当监听的节点释放锁之后,触发回调通知,从而再次去尝试抢占锁。
    总的来说,这两种方案都有各自的优缺点:
    Redis它获取锁的方式简单粗暴,如果获取不到锁,会不断尝试获取锁,消耗性能比较大,但是实现难度比较低。
    Zookeeper如果获取不到锁,只需要添加一个监听器就可以了,消耗性能比较小,但是实现难度比较高。

4、 zookeeper 是如何保证事务的顺序一致性的?

  • zookeeper采用了全局递增的事务Id 来标识,所有的 proposal(提议)在被提出的时候都会加上 zxid,zxid实际上是一个64位的数字,高32位是epoch(时期; 纪元; 世; 新时代)用来标识leader是否发生改变,如果有新的leader产生出来,epoch会自增,然后低32位用来递增计数。
    当产生新的提议时,zookeeper会采用数据库的二阶段提交,首先会向其他的节点发出事务执行请求,如果超过半数的机器都能执行,那么就会提交事务。

5、 zookeeper主从同步机制:

  • 1、当leader 接受到消息请求后,会给消息加上一个全局的事务Id (zxid);
  • 2、leader将带有zxid的消息作为一个提案(proposal)分发给所有的follower;
  • 3、当follower接受到提案后,先把提案写到磁盘,写入成功以后再向leader回复一个ack;
  • 4、当leader 接受到半数以上ack,就会向follower发送提交commit命令,同时自己也执行;
  • 5、当follower接受到commit命令以后,就会提交该消息,从而实现数据同步。

6、分布式集群中为什么会有 Master?

在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能。

7、 zk 节点宕机如何处理?

  • 1、如果是一个 Follower 宕机,只要超过半数的节点正常,集群就能正常提供服务,否则集群就会失效;
  • 2、如果是一个 Leader 宕机,Zookeeper会进入恢复模式,重新选举出新的 Leader。
    Zookeeper本身也是集群,推荐不少于 3 个服务器,而且最好奇数个。

8、说几个 zookeeper 常用的命令?

常用命令:ls get set create delete 等。

9、ZK 如何投票实现Leader选举?

如果 Leader 节点宕机了,为了保证集群继续提供服务,Zookeeper 需要从剩下的 Follower 节点里面去选举一个新的节点作为 Leader,也就是所谓的 Leader 选举。具体的实现是:

  • 1、每一个节点都会向集群里面的其他节点发送一个票据 Vote,这个票据包括三个属性:epoch逻辑时钟,zxid事务id,myid服务器id;然后第一轮投票都会投给自己。
  • 2、每个节点把收到的票据和自己节点的票据做比较,根据 epoch、zxid、myid 的顺序逐一比较,以值最大的一方获胜,比较结束以后就把票投给获胜的节点;
  • 3、通过多轮投票以后,以少数服从多数的方式,最终获得票数最多的节点成为Leader。
    到这里,leader选举就结束啦。
    其中epoch,逻辑时钟,用来标识当前票据是否过期;zxid,事务id,用来表示当前节点最新存储的数据的事务编号; myid,服务器id,在 myid 文件里面填写的;

MQ中间件

10、什么是 RocketMq?

  • RocketMq是一个基于 AMQP 高级消息队列协议的中间件,接受并转发消息。它有4个核心组件,分别是:
  • producer生产者:负责生产和发送消息到 Broker;
  • Exchange交换机:按照一定的规则将消息路由转发到某个队列,对消息进行过虑;
  • Queue队列:用来存储消息,并把消息转发给指定的消费者;
  • consumer消费者:负责从 Broker 中获取消息,并进行相应处理;
    它的工作原理是生产者把消息发送到Exchange交换机上。Exchange交换机把收到的消息根据路由规则,转发给绑定的queue队列,队列再把消息投递给订阅了这个队列的消费者,从而完成消息的异步通讯。

11、什么是消息队列?

消息队列 Message Queue,简称 MQ。
消息队列有很多使用场景,比较常见的有3个:解耦、异步、削峰。

  • 1、应用解耦:把相关联的系统进行职责解耦,比如:生成订单会调用仓库管理系统或积分系统。
  • 2、异步处理:不需要立即处理消息,提高系统的性能,比如:用户注册发送验证码、下单短信通知、发送优惠券等。
  • 3、流量削峰:能够有效的顶住瞬间高并发,防止服务器承受不住导致崩溃,比如秒杀、限时抢购优惠券等。
    比如吞吐量低的中小型公司,一般用 ActiveMQ、RabbitMQ 较为合适,
    大数据、吞吐量高的大型公司一般选用 Kafka 和 RocketMQ。

12、RocketMq的路由类型和发送消息的方式?

它的工作原理是生产者把消息发送到Exchange交换机上,Exchange交换机把收到的消息根据路由规则,转发给绑定的queue队列,最后再把消息投递给订阅了这个队列的消费者,从而完成消息的异步通讯。
在RabbitMQ中,交换机常见的有3种类型,分别是Fanout、Direct 、Topic:

  • Fanout(扇出交换机):类似于广播机制,将消息转发给到所有绑定的队列上,与routingKey(路由键)无关;
  • Direct(直连交换机):完整匹配方式,也就是Routing key和Binding Key完全一致,才把消息发给该队列;
  • Topic(主题交换机):就是Routing Key加了通配符,符合匹配规则的Queue队列都会收到这个消息,#:代表0个或多个单词,*:代表一个单词。

13、死信消息的生命周期?

  • 1、消费者消费业务消息时发生异常,就会返回nck或者reject操作;
  • 2、那么这些消息就会被投递到死信交换机中;
  • 3、死信交换机将消息发送到相应的死信队列;
  • 4、死信队列可以定时重新投递到Broker中,也可以由死信消费者消费。

14、如何保证消息的顺序性?

这个问题是由于不同的消息都发送到了同一个 queue队列中,而这个queue队列又被多个消费者消费。
解决这个问题,我们可以给 RabbitMQ 创建多个 queue队列,每个队列对应一个消费者。比如生产者发送消息的时候,同一个订单号的消息发送到同一个 queue队列中,由于同一个 queue队列的消息是有序的,那么同一个订单号的消息就只会被一个消费者顺序消费,从而保证了消息的顺序性。

15、如何防止消息丢失?

  • 1)、使用事务消息
  • 2)、使用消息确认机制
    消息丢失的场景有下面几种:
  • 1)、生产者发送消息到MQ的过程中丢失
    解决方法: 在生产者端开启comfirm 确认模式,每个消息会分配一个唯一的 id,如果MQ写入了内存中, 就会返回一个ack,告诉你说这个消息ok了,如果MQ没有写入这个消息,会回调一个nack接口,告诉你这个消息失败了,你可以进行重试或抛弃此条消息。
  • 2)、MQ收到消息,写入到内存中,还没消费,服务挂掉了,数据都会丢失
    解决方法:将消息持久化到磁盘,有两个步骤:
    第1步:把该消息设置为持久化,即deliveryMode设置为2,第3个参数设置如下:
    channel.basicPublish(“exchange”, “routingKey”, MessageProperties.PERSISTENT_TEXT_PLAIN, " message".getBytes());
    第2步:把该queue队列设置为持久化,即durable=true,第2个参数设置为true,
    channel.queueDeclare(QUEUE_NAME, true, false, false, null);
  • 3)、消费者刚拿到消息,还没处理,服务挂掉了,MQ又以为消费者处理完了
    解决方式:首先关闭 RabbitMQ 的自动 ack,然后消费者在处理完消息之后,再手动返回ack。这样可以保证,如果你还没处理完,就不会返回ack,那队列就不会删除该消息。
    (关闭 RabbitMQ 的自动 ack,即autoAck=false,第2个参数设置为false
    channel.basicConsume(QUEUE_NAME, true, new DefaultConsumer(channel){});)

16、如何保证消息不被重复消费?

我们为了消息的可靠性,采用了手动ack机制;如果消费者在处理完一个消息之后,还没有手动调用ack,服务就挂了,MQ以为你还还没处理,就把这个消息投递给其他的消费者,就导致了消息被重复消费。
我觉得这个问题可以分为2种场景来对待:

  • 第1种幂等性场景:就是说消息重复消费和消费一次产生的影响是一样的,可以不用处理,比如Redis的set操作,它是天然幂等性的;
  • 第2种非幂等性场景:把消息唯一id保存到 mysql 或者 redis 里面,在处理消息之前先去 mysql 或者 redis 里面,判断一下是否已经消费过了。

17、MQ处理消息失败了怎么办?

一般生产环境中,都会在使用MQ的时候设计两个队列:一个是核心业务队列,一个是死信队列。核心业务队列,就是比如专门用来给订单系统发送订单消息的,然后另外一个死信队列就是用来处理异常情况的。

18、消息基于什么传输?

RabbitMQ 使用channel通道的方式来传输数据,通道是建立在真实的 TCP 连接内的虚拟连接,且通道数量没有限制,大大提升了MQ的处理性能。

19、RocketMQ 底层原理?

RocketMQ 架构主要包含以下四个部分:

  • 1、NameServer:是一个简单的Topic路由注册中心,支持Broker的注册与发现,主要有两个功能:Broker管理(提供心跳检测机制)和路由信息管理(保存Broker的路由信息和用于客户端查询的队列信息);
  • 2、BrokerServer:RocketMQ 的核心组件,主要负责消息的
    1、存储:CommitLog(存储消息的文件);
    2、投递:ConsumeQueue(消息消费队列);
  • 3.查询:IndexFile(索引文件);
  • 4.以及维护消费者的Topic订阅信息和保证服务高可用;
    1、Producer:消息生产者,往Broker发送指定Topic的消息。
    2、Consumer:消息消费者,主动拉取消息来消费,支持集群方式(同一Topic下的一条消息只会发送到同一消费组中的一个消费者)和广播方式(所有的消息会广播发送到所有的消费者)。

20、RocketMQ为什么速度快, 吞吐量?

因为使⽤了顺序存储、页缓存(Page Cache)和异步刷盘;我们在写⼊commitlog的时候是顺序写⼊的,这样⽐随机写⼊的性能就会⾼很多,而且它不是直接写⼊磁盘,⽽是先写⼊页缓存,开启一个异步线程通过零拷贝机制,定时的将缓存中的数据刷到磁盘中,从而保证消息的快速读写。

21、什么是零拷贝?

  • 传统⽂件复制方式:需要对⽂件在内存中进⾏四次复制(内核态到用户态的来回复制)。
  • 零拷⻉:就是减少内核态到用户态的来回复制,它是通过内存映射的机制,直接把内核态里的数据映射到用户态,对文件的操作转化为对内存地址的操作;
    通常有两种⽅式,mmap(RocketMq)和sendfile(kafka)。
    在这里插入图片描述

22、死信队列?

当一条消息消费失败时,经过多次重试依然失败,为了保证消息数据不丢失,需要将消息投入到死信队列中。
死信的来源:

  • 1、消息 TTL(存活时间)过期
  • 2、队列满了,无法再添加数据到队列中
  • 3、消息被拒绝(消费方拒绝应答:basic.reject 或 basic.nack)并且不放回队列中( requeue=false)

总结

都已经看到这里啦,赶紧收藏起来,祝您工作顺心,生活愉快!

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

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

相关文章

LeetCode --- 三数之和

题目描述 三数之和 代码解析 暴力 在做这一道题的时候,脑海里先想出来的是暴力方法,一次排序,将这个数组变为有序的,再通过三次for循环来寻找满足条件的数字,然后将符合条件的数组与之前符合条件的数组进行一一对比…

进来吧,给自己10分钟,这篇文章带你直接学会python

Python的语言特性 Python是一门具有强类型(即变量类型是强制要求的)、动态性、隐式类型(不需要做变量声明)、大小写敏感(var和VAR代表了不同的变量)以及面向对象(一切皆为对象)等特点的编程语言。 获取帮助 你可以很容易的通过Python解释器获取帮助。如果你想知道一个对象(o…

ZYNQ--MIG核配置

文章目录 MIG核配置界面多通道AXI读写DDR3MIG核配置界面 Clock Period: DDR3 芯片运行时钟周期,这个参数的范围和 FPGA 的芯片类型以及具体类型的速度等级有关。本实验选择 1250ps,对应 800M,这是本次实验所采用芯片可选的最大频率。注意这个时钟是 MIG IP 核产生,并输出给…

【算法】顺时针打印矩阵(图文详解,代码详细注释

目录 题目 代码如下: 题目 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则打印出数字:1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 这一道题乍一看,没有包含任何复杂的数据结构和…

使用 Docker 部署 Answer 问答平台

1)介绍 GitHub:https://github.com/apache/incubator-answer Answer 问答社区是在线平台,让用户提出问题并获得回答。用户可以发布问题并得到其他用户的详细答案、建议或信息。回答可以投票或评分,有助于确定有用的内容。标签和分…

“智农”-高标准农田

高标准农田是指通过土地整治、土壤改良、水利设施、农电配套、机械化作业等措施,提升农田质量和生产能力,达到田块平整、集中连片、设施完善、节水高效、宜机作业、土壤肥沃、生态友好、抗灾能力强、与现代农业生产和经营方式相适应的旱涝保收、稳产高产…

mongoDB 优化(1)索引

1、创建复合索引(多字段) db.collection_test1.createIndex({deletedVersion: 1,param: 1,qrYearMonth: 1},{name: "deletedVersion_1_param_1_qrYearMonth_1",background: true} ); 2、新增索引前: 执行查询: mb.r…

miniconda3彻底删除虚拟环境

退出虚拟环境:确保您不在要删除的虚拟环境中。如果在,使用命令 conda deactivate 来退出当前激活的虚拟环境。查看虚拟环境列表:运行命令 conda env list 或 conda info -e 来查看所有存在的虚拟环境及其路径。删除虚拟环境:使用命…

spring boot 整合 minio存储 【使用篇】

导入依赖 <!--minio--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.0.3</version></dependency> yml配置&#xff08;默认配置&#xff09; max-file-size: 200MB 设置文件最大…

python接口自动化(一)--什么是接口、接口优势、类型(详解)

简介 经常听别人说接口测试&#xff0c;接口测试自动化&#xff0c;但是你对接口&#xff0c;有多少了解和认识&#xff0c;知道什么是接口吗&#xff1f;它是用来做什么的&#xff0c;测试时候要注意什么&#xff1f;坦白的说&#xff0c;笔者之前也不是很清楚。接下来先看一下…

C# Socket通信从入门到精通(21)——TCP发送文件与接收文件 C#代码实现

1、前言 我们在开发上位机软件的过程中经常需要发送文件,本文就是介绍如何利用tcp客户端发送文件、tcp服务器端接收文件,也就是所谓的文件传输,而且本文介绍的方法具备以下特点: 1)可配置发送的文件夹和接收的文件夹路径: 2)可自动发送指定文件夹下的所有子目录和文件;…

STM32 DMA入门指导

什么是DMA DMA&#xff0c;全称直接存储器访问&#xff08;Direct Memory Access&#xff09;&#xff0c;是一种允许硬件子系统直接读写系统内存的技术&#xff0c;无需中央处理单元&#xff08;CPU&#xff09;的介入。下面是DMA的工作原理概述&#xff1a; 数据传输触发&am…

IO多路转接

1.select 初识select 系统提供 select 函数来实现多路复用输入 / 输出模型 . select 系统调用是用来让我们的程序监视多个文件描述符的状态变化的 ; 程序会停在 select 这里等待&#xff0c;直到被监视的文件描述符有一个或多个发生了状态改变 ; select函数模型 select的函…

Vue开发实例(三)项目引入Element-UI

项目引入Element-UI 一、引入Element-UI二、注册组件1、vue2使用element-ui2、vue3使用element-ui 三、使用Element组件1、轻微改造2、验证element是否生效 一、引入Element-UI npm i element-ui --save npm install element-ui -S等待安装完成 二、注册组件 1、vue2使用ele…

C++真题列表

题目解析&#xff1a;RAM是闪存&#xff0c;只要一关机一拔电&#xff0c;就会丢失数据 题目解答&#xff1a;A 题目解析&#xff1a;TXT格式是文本文档 题目解答&#xff1a;B 题目解析&#xff1a;IP地址中每一个字节的取值范围是[0~255]&#xff0c;是不可能有256的 题目…

Mongodb基础(node.js版)

一、Mongodb 介绍 Mongodb 是一个文档数据库&#xff0c;以文档形式存储数据&#xff0c;格式类似于 JSON 与 Mysql 的特点及选型对照 MongodbMysql关系类型非关系型关系型存储类型文档存储&#xff08;类似于写 Word &#xff09;表格存储 &#xff08;类似于写 Excle&…

【Python】进阶学习:pandas--isin()用法详解

【Python】进阶学习&#xff1a;pandas–isin()用法详解 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订阅…

midjourney提示词语法

更高级的提示可以包括一个或多个图像URL、多个文本短语和一个或更多个参数 Image Prompts 可以将图像URL添加到提示中&#xff0c;以影响最终结果的样式和内容。图像URL总是位于提示的前面。 https://docs.midjourney.com/image-prompts Text Prompt 要生成的图像的文本描述。…

C++_运算符_逻辑运算符

逻辑运算符的作用 用于根据表达式的值返回真值或假值 逻辑运算符有以下符号 示例1&#xff1a;逻辑非 示例2&#xff1a;逻辑与 总结 同真为真&#xff0c;其余为假 示例3&#xff1a;逻辑或 总结 同假为假&#xff0c;其余为真

Git 如何上传本地的所有分支

Git 如何上传本地的所有分支 比如一个本地 git 仓库里定义了两个远程分支&#xff0c;一个名为 origin&#xff0c; 一个名为 web 现在本地有一些分支是 web 远程仓库没有的分支&#xff0c;如何将本地所有分支都推送到 web 这个远程仓库上呢 git push web --all