自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

NameServer、Zookeeper,傻傻分不清楚

云計算
消息隊列RocketMQ版是阿里云基于Apache RocketMQ構(gòu)建的低延遲、高并發(fā)、高可用、高可靠的分布式消息中間件。

[[386520]]

本文轉(zhuǎn)載自微信公眾號「大魚仙人」,作者大魚。轉(zhuǎn)載本文請聯(lián)系大魚仙人公眾號。

消息隊列RocketMQ版是阿里云基于Apache RocketMQ構(gòu)建的低延遲、高并發(fā)、高可用、高可靠的分布式消息中間件。

我們知道RocketMQ是個消息隊列,這個消息隊列是分為多個組件的,其中包括broker、producer、consumer等,那么這些個組件之間如何交互呢?或者說它們?nèi)绾潍@得對方的狀態(tài)呢

 

大魚相信聰明的你應(yīng)該已經(jīng)猜到了,就是通過一個注冊中心來控制,其實(shí)大魚本人我在寫這篇文章之前一直在糾結(jié)到底如何稱呼NameServer在RocketMQ中的地位呢?

說是大腦吧,但是它又不完全算是指揮中心,也沒有存儲消息(消息存儲在broker中),大腦中應(yīng)該是存儲這這些才有資格叫做大腦吧;要說不是大腦吧,它又存在一部分的指揮作用,producer發(fā)送消息,需要先通過NameServer獲取到broker和Topic的對應(yīng)關(guān)系,獲取到broker的地址信息,再去長連接broker來發(fā)送消息,而且還和broker之間有著心跳機(jī)制來維持broker的存活狀態(tài),維持整個集群的穩(wěn)定性和可用性

所以,大魚我給NameServer起名叫做 偽大腦 ;

啥玩意?偽大腦,那是不是還有真大腦呢?真大腦是什么?

我真是太喜歡好奇的你了,一猜你就是風(fēng)華正茂,愛好學(xué)習(xí)的中華好兒女,沒錯,我賣關(guān)子其實(shí)就是下一篇咱們要一起學(xué)習(xí)的broker,這是RocketMQ中最核心的了,因為很多邏輯控制都是在這里邊完成(定時延時、半消息),還有存儲消息的文件、存儲消費(fèi)offset的文件等等

 

NameServer

NameServer是什么

知其然,再知其所以然,那到底NameServer是個什么東西呢?

NameServer是一個非常簡單的Topic路由注冊中心,其角色類似Dubbo中的zookeeper,支持Broker的動態(tài)注冊與發(fā)現(xiàn)。NameServer是一個幾乎無狀態(tài)節(jié)點(diǎn),可集群部署,節(jié)點(diǎn)之間無任何信息同步。

NameServer存儲Topic和Broker的信息,Broker啟動的時候會向所有的NameServer注冊。Producer在發(fā)送消息之前會先從NameServer獲取Broker地址列表,按照負(fù)載均衡算法從列表中選擇一臺Broker服務(wù)器發(fā)送消息

NameServer和Broker保持長連接,每隔30s檢測Broker是否存活,如果Broker宕機(jī),從路由注冊表中刪除。路由變化不會馬上通知Producer,這樣實(shí)現(xiàn)降低了NameServer實(shí)現(xiàn)復(fù)雜度,Producer會通過容錯機(jī)制來保證消息發(fā)送高可用。

 

Producer與Name Server集群中的其中一個節(jié)點(diǎn)(隨機(jī)選擇)建立長連接,定期從Name Server取Topic路由信息,并向提供Topic服務(wù)的Master建立長連接,且定時向Master發(fā)送心跳。Producer完全無狀態(tài),可集群部署。

Consumer與Name Server集群中的其中一個節(jié)點(diǎn)(隨機(jī)選擇)建立長連接,定期從Name Server取Topic路由信息,并向提供Topic服務(wù)的Master、Slave建立長連接,且定時向Master、Slave發(fā)送心跳。Consumer既可以從Master訂閱消息,也可以從Slave訂閱消息,訂閱規(guī)則由Broker配置決定。

NameServer集群

RocketMQ集群,應(yīng)該是線上采用的相當(dāng)多的一種架構(gòu)了,分為四個主要組成部分:生產(chǎn)者集群、消費(fèi)者集群、NameServer集群和Broker集群,其中的NameServer集群是什么樣子的呢?這個還挺有意思的,和別的集群不太一樣,一起來看看為啥

我們了解的集群,一般都是互幫互助,起到一個高可用的作用;絕大多數(shù)集群應(yīng)該都是這個樣子的,而NameServer集群卻不是這個樣子的,NameServer集群說白了其實(shí)屬于一個偽集群,為什么這么說呢?

因為NameServer集群中的多個節(jié)點(diǎn)是互不交互的,就是等同于多個獨(dú)立的NameServer機(jī)器部署在NameServer集群中,每個機(jī)器都可以單獨(dú)支持這個集群的運(yùn)轉(zhuǎn),多個機(jī)器的作用其實(shí)就是備份的作用

 

NameServer集群如何部署

NameServer 是整個集群的路由中心,如果沒有了它,生產(chǎn)者往哪個 Broker 投遞消息都不知道,沒有了它,會很麻煩!

為了保證高可用性,NameServer 必然是需要支持多臺部署的。如果 NameServer 就部署一臺機(jī)器的話,一旦它宕機(jī)了會導(dǎo)致 RocketMQ 集體出現(xiàn)故障。

所以多機(jī)器部署保證了任何一臺 NameServer 宕機(jī),其他機(jī)器上的 NameServer 可以繼續(xù)對外提供服務(wù)。

如果NameServer集群中的一個機(jī)器掛掉了怎么辦,對集群有什么影響

對于整個RocketMQ集群來說問題不大,因為設(shè)計優(yōu)秀的RocketMQ集群不會因為一臺NameServer機(jī)器掛掉而導(dǎo)致整個集群受影響甚至不可用。一般我們會有報警系統(tǒng)來報警關(guān)于NameServer機(jī)器掛掉的信息,有相應(yīng)的運(yùn)維人員再去處理

 

NameServer作用

NameServer是一個非常簡單的Topic路由注冊中心,其角色類似Dubbo中的zookeeper,支持Broker的動態(tài)注冊與發(fā)現(xiàn)。NameServer是一個幾乎無狀態(tài)節(jié)點(diǎn),可集群部署,節(jié)點(diǎn)之間無任何信息同步。

NameServer在RocketMQ集群中起到了類似于注冊中心的作用,我們先來看下NameServer的源碼架構(gòu)

 

其實(shí)結(jié)構(gòu)也很簡單,不算復(fù)雜,大家如果有興趣研究,可以花點(diǎn)時間去研究,源碼地址:

https://github.com/rocketmq

NameServer在RocketMQ中的作用大概大魚同學(xué)給分了三類,叫做路由管理、路由發(fā)現(xiàn)和路由刪除,也很好理解,來,我給大家簡單解釋下

  • 路由管理就是保存著broker的活躍列表和Topic對應(yīng)的關(guān)系
  • 路由注冊和發(fā)現(xiàn)就是Topic對應(yīng)的broker信息發(fā)生變化時的更新(非實(shí)時性)
  • 路由刪除就是對于broker機(jī)器宕機(jī)或者關(guān)閉時自動刪除相應(yīng)路由

我們知道broker和NameServer的關(guān)系是很緊密的,單個broker會和所有的NameServer保持長連接,broker啟動時會輪詢所有的NameServer并進(jìn)行注冊

broker每隔30秒(此時間沒有辦法更改的哦,切記哦)會向所以的NameServer發(fā)送心跳,心跳包含了所有的Topic信息

由此可以看出:如果broker中包含太多Topic,心跳信息過大的話可能會造成網(wǎng)絡(luò)傳輸較慢

NameServer每隔10秒也會掃描所有存活著的broker的,這個時間也是無法更改的,若某個連接2分鐘內(nèi)(當(dāng)前時間與最后更新時間差值超過2分鐘,此時間無法更改)沒有發(fā)送心跳數(shù)據(jù),則斷開連接,一旦連接斷開,nameserver會感知,感知會有稍稍的延遲,為啥延遲我應(yīng)該不用說了吧?

接著就是更新topc與隊列的對應(yīng)關(guān)系,但不會通知生產(chǎn)者和消費(fèi)者

路由管理:保存著broker的活躍列表和Topic對應(yīng)的隊列列表

NameServer保存著活躍的broker列表,包括master和slave;NameServer用來保存所有的Topic和Topic對應(yīng)的所有隊列的列表;NameServer用來保存所有的broker的filter列表

這些在RouteInfoManager這個類中都有

 

每個屬性通過名字就能清楚的知道是什么意思,之所以能用非線程安全的HashMap,是因為有讀寫鎖lock來對HashMap的修改做保護(hù)。

我們注意到保存broker的Map有兩個,即brokerAddrTable用來保存所有的broker列表和brokerLiveTable用來保存當(dāng)前活躍的broker列表,而BrokerData用來保存broker的主要新增,而BrokerLiveInfo只用來保存上次更新(心跳)時間

 

你幾乎可以在NameServer這里知道topic相關(guān)的所有信息,包括topic有哪些隊列,這些隊列在那些broker上等。

DefaultRequestProcessor是NameServer的默認(rèn)請求處理器,他處理了定義在rocketmq-common模塊中RequestCode定義的部分請求,比如注冊broker、注銷broker、獲取topic路由、刪除topic、獲取broker的topic權(quán)限、獲取NameServer的所有topic等

路由注冊和發(fā)現(xiàn):Broker的啟動注冊和Topic的關(guān)系變動

Broker在啟動時向所有的NameServer心跳語句,每隔30S向所有NameServer發(fā)起心跳包。NameServer收到心跳包后更新緩存。NameServer每隔10S掃描brokerLiveTable,如果連續(xù)120S沒有收到心跳包,則NameServer移除Broker的路由信息同時關(guān)閉Socket連接。

路由注冊在broker啟動時觸發(fā),broker啟動時會和所有NameServer創(chuàng)建心跳連接,向NameServer發(fā)送Broker的相關(guān)信息。NameServer在RouteInfoManager類中維護(hù)了Broker相關(guān)信息的緩存,進(jìn)行更新動作。更新時用了讀寫鎖,既保證了極高并發(fā)場景下的讀效率,又避免了并發(fā)修改緩存。

 

路由發(fā)現(xiàn):RocketMQ的路由發(fā)現(xiàn)是非實(shí)時的。當(dāng)topic對應(yīng)的路由信息發(fā)生變化,NameServer并不會通知給客戶端。而是由客戶端定時拉取Topic對應(yīng)的最新路由。不實(shí)時的路由發(fā)現(xiàn)引起的問題由客戶端進(jìn)行解決,保證了NameServer邏輯的簡潔??蛻舳硕〞r向NameServer發(fā)起請求GET_ROUTEINFO_BY_TOPIC,獲取對應(yīng)的信息

路由刪除:對于宕機(jī)或者關(guān)閉的broker,自動刪除相應(yīng)的路由信息

路由刪除的觸發(fā)點(diǎn)有兩個:

  • NameServer啟動時開啟的定時任務(wù),每隔10s掃描一次brokerLiveTable,檢測上次心跳包與當(dāng)前系統(tǒng)時間差,如果時間差大于120s,則移除Broker的相關(guān)信息。
  • Broker正常關(guān)閉,會向NameServer發(fā)送UNREGISTER_BROKER消息。

其實(shí)初期RocketMQ采用的是zookeeper作為注冊中心的,后來為什么改成自研的NameServer了?

這個問題其實(shí)我也不想太多的多說,這個可能需要了解zookeeper,如果不了解這個東西的話,其實(shí)我說了也是沒啥大用的

 

首先,zookeeper中最主要的功能就是master的選舉,但是呢?對于RocketMQ不太合適,你想啊,RocketMQ中的master并不會存在全部的Topic信息,所以選擇master沒什么意義

其次,對于RocketMQ來說,這個注冊中心的作用不僅要保存相關(guān)的信息(broker活躍列表、Topic對應(yīng)信息等),還有就是需要一些邏輯來處理相應(yīng)的數(shù)據(jù),比如每隔10秒檢測一次活躍的broker來更新列表,這些邏輯如果換做是zookeeper的客戶端來處理的話,算是比較麻煩的

 

因此,既然zookeeper對于RocketMQ來說是屬于一個重量級的注冊中心,所以不如自己寫一個簡易的注冊中心來實(shí)現(xiàn),像上面說的集群,NameServer集群是屬于偽集群,節(jié)點(diǎn)之間不存在相應(yīng)的交互,只是起到一個備份的作用,這樣使得RocketMQ集群變得更加靈活

 

責(zé)任編輯:武曉燕 來源: 大魚仙人
相關(guān)推薦

2021-07-27 07:31:16

JavaArrayList數(shù)組

2022-05-15 21:52:04

typeTypeScriptinterface

2024-02-29 09:08:56

Encoding算法加密

2020-10-30 08:20:04

SD卡TF卡存儲

2018-12-17 12:30:05

Kubernetes存儲存儲卷

2018-05-22 16:24:20

HashMapJavaJDK

2020-03-03 17:35:09

Full GCMinor

2023-02-27 15:46:19

數(shù)據(jù)元元數(shù)據(jù)

2023-09-03 21:18:07

Python編程語言

2021-02-08 23:47:51

文件存儲塊存儲對象存儲

2016-11-04 12:51:46

Unix網(wǎng)絡(luò)IO 模型

2022-02-25 09:14:33

類變量共享實(shí)例變量

2021-11-09 06:01:35

前端JITAOT

2024-11-04 00:00:03

viewportDOMSPA

2021-01-13 08:10:26

接口IEnumeratorIEnumerable

2020-11-11 07:32:18

MySQL InnoDB 存儲

2023-04-11 15:57:49

JavaScriptCSSHTML

2021-02-14 22:33:23

Java字符字段

2019-11-21 14:22:12

WiFiWLAN區(qū)別

2021-11-01 13:10:48

私有云混合云行業(yè)云
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號