【RocketMQ】NameServer總結

来源:https://www.cnblogs.com/shanml/archive/2023/05/25/17433314.html
-Advertisement-
Play Games

NameServer是一個註冊中心,提供服務註冊和服務發現的功能。NameServer可以集群部署,集群中每個節點都是對等的關係(沒有像ZooKeeper那樣在集群中選舉出一個Master節點),節點之間互不通信。 **服務註冊** Broker啟動的時候會向所有的NameServer節點進行註冊, ...


NameServer是一個註冊中心,提供服務註冊和服務發現的功能。NameServer可以集群部署,集群中每個節點都是對等的關係(沒有像ZooKeeper那樣在集群中選舉出一個Master節點),節點之間互不通信。
服務註冊
Broker啟動的時候會向所有的NameServer節點進行註冊,註意這裡是向集群中所有的NameServer節點註冊,而不是只向其中的某些節點註冊,因為NameServer每個節點都是對等的,所以Broker需要向每一個節點進行註冊,這樣每一個節點都會有一份Broker的註冊信息。

服務發現
Broker向NameServer註冊以後,生產者Producer和消費者Consumer就可以從NameServer中獲取所有註冊的Broker信息,並從中選取Broker進行消息的發送和消費。

以生產者為例,在NameServer集群部署模式下,生產者會從多個NameServer中隨機選取一個進行通信,從中拉取所有Broker的註冊信息,並將拉取到的信息進行緩存,生產者知道了Broker的信息後,就可以得知Topic的分佈情況,然後選取一個消息隊列,與其所在的Broker通信進行消息的發送。如果通信的Nameservre宕機,消費者會輪詢選擇下一個NameServer。

為什麼需要NameServer?

在使用RocketMQ的時候,為了提升性能以及應對高併發的情況,一般都會使用多個Broker進行集群部署,假設沒有註冊中心,對於Broker來說,如果想獲取到集群中所有的Broker信息(生產者和消費者需要通過某個Broker獲取整個集群的信息,從而得到Topic的分佈情況),每個Broker都需要與其他Broker通信來交換信息,以此來得到集群內所有Broker的信息,在Broker數量比較大的情況下,會造成非常大的通信壓力。

為什麼不使用zookeeper這樣的分散式協調組件?
首先zookeeper的實現複雜,引入zookeeper會增加系統的複雜度,並且zookeeper在CAP中選擇了CP,也就是一致性和分區容錯性,從而犧牲了可用性,為了保持數據的一致性會在一段時間內會不可用。

而NameServer在實現上簡單,RocketMQ的設計者也許認為對於一個消息隊列的註冊中心來說,一致性與可用性相比,可用性更重要一些,至於一致性可以通過其他方式來解決。

假如選擇了CP的ZooKeeper,先不考慮其他原因,在ZooKeeper不可用的時候,如果有消費者或生產者剛好需要從NameServer拉取信息,由於服務不可用,導致生產者和消費者無法進行消息的生產和發送,在高併發或者數據量比較大的情況下,大量的消息無法發送/無法消費影響是極大的,而如果選擇AP,即便數據暫時處於不一致的狀態,在心跳機制的作用下也可以保證數據的最終一致性,所以RocketMQ選擇了自己實現註冊中心,簡單並且輕量

舉個例子,假如集群中有三個Broker(分別為 A、B、C),向三台NameServer進行了註冊(也分別為A、B、C),消費者從NameServer中獲取到了三個Broker的信息,如果此時BrokerA需要停止服務,分別通知三台NameServer需要下線,從NameServer中剔除該Broker的信息,由於網路或者其他原因,NameServer A和B收到了下線的請求,NameServer C並未收到,此時就處於數據不一致的狀態,如果某個消費者是與NameServer C進行通信,會認為Broker還處於可用的狀態:

對於這種情況,首先NameServer與Broker之間會有一個心跳機制,NameServer定時檢測在某個時間範圍內是否收到了Broker發送的心跳請求,如果未收到,會認為該Broker不可用,將其剔除(在下麵會講到),所以對於NameServer來說,儘管數據會暫時處於不一致的狀態,但是可以保證過一段時間之後恢複數據的一致性,也就是最終一致性。

對於消費者來說,既然可以從NameServer C中獲取到Broker A的信息,那麼消費者就認為Broker A可用,如果發送的消息所在的消息隊列在Broker A中,就會與Broker A通信進行發送,但實際上Broker A實際上是不可用的,消息會發送失敗,所以RocketMQ設計了消息重試機制以及故障延遲機制。

Broker註冊

Broker啟動後會開啟定時向NameServer進行註冊(發送心跳包)的任務,發送心跳包的時間間隔可以在配置文件中進行設置,但是最長不能超過10s,也就是說Broker最長10秒鐘會向Nameserver發送一次心跳包。

NameServer收到Broker的註冊請求(心跳包)後,會判斷Broker之前是否已經註冊過,如果未註冊過將其加入到註冊的Broker集合brokerAddrTable中,同時也會記錄收到註冊請求的時間,將其加入到brokerLiveTable中,裡面記錄了NameServer收到每個Broker發送心跳包的時間,在進行心跳檢測的時候根據這個時間戳來判斷是否在規定時間內未收到該Broker發送的心跳包。

讀寫鎖
由於NameServer可能同時收到多個Broker的註冊以及生產者或者消費者的拉取請求,為了保證數據的一致性(因為有讀寫請求同時發生或者寫與寫請求同時發生),在處理相關請求的時候需要加鎖,為了提高性能,使用了ReadWriteLock讀寫鎖,處理註冊請求時會先添加寫鎖,處理拉取請求時添加讀鎖,這樣如果某一時刻都是讀的請求可以同時進行,互不影響,如果有寫請求,其他請求就需要等鎖釋放才可以進行往下進行。如果不使用讀寫鎖,直接對所有的請求加鎖,會影響性能,實際上讀與讀之間並不需要加鎖。

心跳檢測

Nameserver在啟動的時候會開啟一個用於心跳檢測的定時任務(每10s執行一次),定時掃描處於不活躍狀態的Broker,如果在規定時間內未收到某個Broker的心跳包,會認為此Broker不可用,需要將其進行剔除。

上面說到brokerLiveTable保存了當前NameServer收到的心跳數據,裡面記錄了每一個Broker最近進行註冊/發送心跳的時間戳,所以只需遍歷brokerLiveTable,獲取每一個Broker最近一次發送心跳的時間進行判斷,如果上一次發送心跳的時間 + 過期時間(120s) 小於 當前時間,也就是超過120s沒有收到某個Broker的心跳包,則認為此Broker已下線,將Broker移除

Broker下線

正常下線
當Broker下線的時候會向NameServer發起取消註冊的請求,NameServer收到請求後會將Broker剔除。

異常下線

如果Broker異常宕機,或者發送給NameServer的取消註冊請求由於某些原因並未發送成功,NameServer可能並未感知到Broker的下線,由於心跳機制定時檢測的功能,會在一段時間後發現未收到Broker的心跳請求,主動將Broker剔除。

生產者和消費者

生產者和消費者都會定時從NameServer中更新Broker的註冊信息,預設是30s進行一次更新:

public class MQClientInstance {
    private void startScheduledTask() {
         this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                try {
                   // 更新路由信息 MQClientInstance.this.updateTopicRouteInfoFromNameServer();
                } catch (Exception e) {
                    log.error("ScheduledTask updateTopicRouteInfoFromNameServer exception", e);
                }
            }
        }, 10, this.clientConfig.getPollNameServerInterval(), TimeUnit.MILLISECONDS);
    }
}

對應的相關源碼可參考:

【RocketMQ】【源碼】NameServer的啟動
【RocketMQ】【源碼】Broker服務註冊


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.轉換 轉換(transform)是CSS3中具有顛覆性的特征之一,可以實現元素的位移、旋轉、縮放等效果。 轉換(transform)可以簡單理解為變形。 移動:translate 旋轉:rotate 縮放:scale 1.1 二維坐標系 2D轉換是改變在二維平面上的位置和形狀的一種技術。 1.2 ...
  • > 隨著人工智慧技術的不斷發展,阿裡體育等IT大廠,推出的“樂動力”、“天天跳繩”AI運動APP,讓**雲上運動會、線上運動會、健身打卡、AI體育指導**等概念空前火熱。那麼,能否將這些在APP成功應用的場景搬上小程式,分享這些概念的紅利呢?本系列文章就帶您一步一步從零開始開發一個AI運動小程式,本 ...
  • 相信很多公司的前端開發人員都會選擇使用vue+element-ui的形式來開發公司的管理後臺系統,基於element-ui很豐富的組件生態,我們可以很快速的開發管理後臺系統的頁面(管理後臺系統的頁面也不複雜,大多都是分頁查詢類需求和增刪改查)。但一個前端框架有優點,就必然會有一些缺點或bug存在,e... ...
  • 寫這篇的目的是,今天在重新學習javascript時發現了HttpOnly這個標簽,所以專門的mark了下。 誰在什麼時候發明瞭HttpOnly 2002年微軟為ie6的sp1創造了HttpOnly 什麼是HttpOnly HttpOnly是包含在http返回頭Set-Cookie裡面的一個附加的f ...
  • 本文將學習如何使用滾動控制 ScrollControls 來控制模型的的動畫播放和相機動畫,通過滾動滑鼠滾輪或者上下移動觸摸板,來控制模型的動畫播放進度或者相機的方位視角,從而呈現出驚艷的視覺效果。通過本文的閱讀和案例頁面的實現,你將學習到的知識包括:R3F 生態中的 ScrollControls、... ...
  • 如果你有 *n* 個緩存伺服器,一個常見的負載均衡方式是使用以下的哈希方法: *伺服器索引 = 哈希(鍵) % N*,其中 *N* 是伺服器池的大小。 讓我們通過一個例子來說明這是如何工作的。如表5-1所示,我們有4台伺服器和8個字元串鍵及其哈希值。 ![image-2023052022160981 ...
  • ### GC 優化 #### 1.防止大對象Buffer到記憶體中 **現象**:當大包請求時,YGC 耗時嚴重 **原因**:預設情況下 Zuul2 並不會緩存請求體(DirectByteBuffer),也就意味著它會先發送接收到的請求 Headers 到後端服務,之後接收到請求體再繼續發送到後端服 ...
  • **我是 javapub,一名 `Markdown` 程式員從👨‍💻,八股文種子選手。** **面試官: 上個面試官對你的基礎有了一定瞭解,聽說你小子很不錯!下麵我們聊點有深度的。** **面試官: 簡單介紹下 CAS 你瞭解什麼?** **候選人:** CAS是Compare And Swap ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...