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.pswp.cn/news/716388.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716388.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716388.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

設計模式之策略模式詳解

目錄 什么是策略模式 應用場景 業務場景實現 抽象類 實現類 Context上下文 測試類 策略模式的優缺點 什么是策略模式 他將定義的算法家族、分別封裝起來,讓他們之間可以相互替換,從而讓算法的變化不會影響到使用算法的用戶。 策略模式使用的就是…

idea出現莫名其妙錯的時候

正常情況idea使用起來都很順手,但是當項目比較多的時候,可能出現莫名奇妙的錯誤,比如導入的包始終報錯java: 程序包com不存在,或者引入自己寫的包也不存在,或者始終出現紅線但是排查之后沒有問題的情況,這種…

進來吧,給自己10分鐘,這篇文章帶你直接學會python

Python的語言特性 Python是一門具有強類型(即變量類型是強制要求的)、動態性、隱式類型(不需要做變量聲明)、大小寫敏感(var和VAR代表了不同的變量)以及面向對象(一切皆為對象)等特點的編程語言。 獲取幫助 你可以很容易的通過Python解釋器獲取幫助。如果你想知道一個對象(o…

OJ:鏈表的中間結點

876. 鏈表的中間結點 - 力扣(LeetCode) 思路 思路:首先最容易想到的思路是什么呢,就是先遍歷一遍鏈表,用一個值count來記錄鏈表的長度,然后我們運用除法,/2,結果是幾,就…

【C++干貨基地】揭秘C++11常用特性:內聯函數 | 范圍for | auto自動識別 | nullptr指針空值

🎬 鴿芷咕:個人主頁 🔥 個人專欄: 《C干貨基地》《粉絲福利》 ??生活的理想,就是為了理想的生活! 引入 哈嘍各位鐵汁們好啊,我是博主鴿芷咕《C干貨基地》是由我的襄陽家鄉零食基地有感而發,不知道各位的…

平臺工程: 用Backstage構建開發者門戶 - 2

本文介紹了如何使用開源Backstage構建自己的開發者門戶,并基于此實踐平臺工程。本系列共兩篇文章,這是第二篇。原文: Platform Engineering: Building Your Developer Portal with Backstage — Part 2 在本教程第一部分中我們了解了Backstage這個用于構…

外貿網站模板建站

測繪檢測wordpress外貿主題 簡潔實用的wordpress外貿主題,適合做測繪檢測儀器設備的外貿公司使用。 https://www.jianzhanpress.com/?p5337 白馬非馬衣服WordPress外貿建站模板 白馬非馬服裝行業wordpress外貿建站模板,適用于時間服裝企業的官方網站…

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

Git 如何上傳本地的所有分支 比如一個本地 git 倉庫里定義了兩個遠程分支,一個名為 origin, 一個名為 web 現在本地有一些分支是 web 遠程倉庫沒有的分支,如何將本地所有分支都推送到 web 這個遠程倉庫上呢 git push web --all

pytorch loss函數整理

變量名解釋 logits:未經過normalize(未經過激活函數處理)的原始分數,例如一個mlp將特征映射到num_target_class維的輸出tensor就是logits。 probs:probabilities的簡寫,logits經過sigmoid函數,…

Doris實戰——銀聯商務實時數倉構建

目錄 前言 一、應用場景 二、OLAP選型 三、實時數倉構建 四、實時數倉體系的建設與實踐 4.1 數倉分層的合理規劃 4.2 分桶分區策略的合理設置 4.3 多源數據遷移方案 4.4 全量與增量數據的同步 4.5 離線數據加工任務遷移 五、金融級數倉穩定性最佳實踐 5.1 多租戶資…

Jenkins的Pipeline概念

文章目錄 Pipeline什么是Jenkins Pipeline聲明式和腳本式Pipeline語法為何使用PipelinePipeline概念PipelineNodeStageStep Pipeline語法概述聲明式Pipeline腳本式Pipeline Pipeline示例 參考 Pipeline 什么是Jenkins Pipeline Jenkins Pipeline是一套插件,它支持…

【Django】model模型—模型繼承

Django中三種繼承風格 抽象基類:僅將父類用于子類公共信息的載體,這樣的父類永遠都不會單獨使用。多表繼承:繼承了一個模型(可能來源其它應用),且想要每個模型都有對應的數據表。代理模型:只想…

JProfiler相關問題及答案(2024)

1、JProfiler是什么及其用途 JProfiler是一款功能豐富的商業Java性能剖析(profiling)工具,它主要面向開發者和性能分析師,用于監測和分析Java應用程序的運行時行為。以下是對JProfiler的一些詳細介紹和它的主要用途: …

webpack的一些知識

核心 webpack 是用來搭建前端工程的它運行在node環境中,它所做的事情,簡單來說,就是打包具體來說,就是以某個模塊作為入口,根據入口分析出所有模塊的依賴關系,然后對各種模塊進行合并、壓縮,形…

洛谷P1157 組合的輸出

深搜板子加一點點修改&#xff0c;適合初學者體會深搜&#xff0c;具體看代碼 題目鏈接 ACcode #include<bits/stdc.h>using namespace std;int a, b;bitset<50>vis;//剪枝 int d[50];void dfs(int x) {if (x b 1) {for (int i 1;i < b;i)cout << se…

HBM(High Bandwidth Memory)

選擇正確的高帶寬內存 構建高性能芯片的選擇越來越多&#xff0c;但附加內存的選擇卻幾乎沒有變化。為了在汽車、消費和超大規模計算中實現最大性能&#xff0c;選擇取決于一種或多種 DRAM&#xff0c;而最大的權衡是成本與速度。 盡管多年來人們一直在努力用更快、更便宜或更…

Linux:kubernetes(k8s)搭建mater節點(kubeadm,kubectl,kubelet)(2)

安裝k8有多種方式如&#xff1a; minikube kubeadm 二進制安裝 命令行工具 我這里就使用kubeadm進行安裝 環境 3臺centos7 master ip &#xff1a;192.168.113.120 2G運存 2內核 node1 ip &#xff1a;192.168.113.121 2G運存 2內核 node2 ip &#xff1a;192.168.1…

重構與設計模型的完美融合:構建穩定可擴展系統的關鍵步驟

在軟件開發的漫長旅程中&#xff0c;系統的穩定性和可擴展性一直是開發者們追求的目標。為了實現這一目標&#xff0c;重構和設計模型成為了不可或缺的兩個關鍵元素。本文將探討如何通過重構&#xff0c;使系統更穩定、更具可擴展性&#xff0c;并深入研究如何將重構與設計模型…

JavaEE:多線程(3):案例代碼

目錄 案例一&#xff1a;單例模式 餓漢模式 懶漢模式 思考&#xff1a;懶漢模式是否線程安全&#xff1f; 案例二&#xff1a;阻塞隊列 可以實現生產者消費者模型 削峰填谷 接下來我們自己實現一個阻塞隊列 1.先實現一個循環隊列 2. 引入鎖&#xff0c;實現線程安全 …

運用qsort函數進行快排并使用C語言模擬qsort

qsort 函數的使用 首先qsort函數是使用快速排序算法來進行排序的&#xff0c;下面我們打開官網來查看qsort是如何使用的。 這里有四個參數&#xff0c;首先base 是至待排序的數組的首元素的地址&#xff0c;num 是值這個數組的元素個數&#xff0c;size 是指每個元素的大小&am…