阿裡巴巴是如何打通 CMDB,實現就近訪問的?

来源:https://www.cnblogs.com/javastack/archive/2019/01/11/10256401.html
-Advertisement-
Play Games

CMDB在企業中,一般用於存放與機器設備、應用、服務等相關的元數據。當企業的機器及應用達到一定規模後就需要這樣一個系統來存儲和管理它們的元數據。有一些廣泛使用的屬性,例如機器的IP、主機名、機房、應用、region等,這些數據一般會在機器部署時錄入到CMDB,運維或者監控平臺會使用這些數據進行展示或 ...


CMDB在企業中,一般用於存放與機器設備、應用、服務等相關的元數據。當企業的機器及應用達到一定規模後就需要這樣一個系統來存儲和管理它們的元數據。有一些廣泛使用的屬性,例如機器的IP、主機名、機房、應用、region等,這些數據一般會在機器部署時錄入到CMDB,運維或者監控平臺會使用這些數據進行展示或者相關的運維操作。

在服務進行多機房或者多地域部署時,跨地域的服務訪問往往延遲較高,一個城市內的機房間的典型網路延遲在1ms左右,而跨城市的網路延遲,例如上海到北京大概為30ms。此時自然而然的一個想法就是能不能讓服務消費者和服務提供者進行同地域訪問。

我們在集團內部的實踐中,這樣的需求是通過和CMDB打通來實現的。Nacos的服務發現組件中,對接CMDB,然後通過配置的訪問規則,來實現服務消費者到服務提供者的同地域優先。

圖1 服務的同地域優先訪問

這實際上就是一種負載均衡策略,在Nacos的規劃中,豐富的服務端的可配置負載均衡策略是我們的重要發展方向,這與當前已有的註冊中心產品不太一樣。在設計如何在開源的場景中,支持就近訪問的時候,與企業自帶的CMDB集成是我們考慮的一個核心問題。除此之外,我們也在考慮將Nacos自身擴展為一個實現基礎功能的CMDB。無論如何,我們都需要能夠從某個地方獲取IP的環境信息,這些信息要麼是從企業的CMDB中查詢而來,要麼是從自己內置的存儲中查詢而來。

CMDB插件機制

先不考慮如何將CMDB的數據應用於負載均衡,我們需要首先在Nacos里將CMDB的數據通過某種方法獲取。在實際使用中,基本上每個公司都會通過購買或者自研搭建自己的CMDB,那麼為了能夠解耦各個企業的CMDB具體實現,一個比較好的策略是使用SPI機制,約定CMDB的抽象調用介面,由各個企業添加自己的CMDB插件,無需任何代碼上的重新構建,即可在運行狀態下對接上企業的CMDB。

圖2 Nacos CMDB SPI機制原理

如圖2所示,Nacos定義了一個SPI介面,裡面包含了與第三方CMDB約定的一些方法。用戶依照約定實現了相應的SPI介面後,將實現打成jar包放置到Nacos安裝目錄下,重啟Nacos即可讓Nacos與CMDB的數據打通。整個流程並不複雜,但是理解CMDB SPI介面里方法和相應概念的含義不太簡單。在這裡對CMDB機制的相關概念和介面含義做一個詳細說明。

CMDB抽象概念

實體(Entity)

實體是作為CMDB里數據的承載方,在一般的CMDB中,一個實體可以指一個IP、應用或者服務。而這個實體會有很多屬性,例如IP的機房信息,服務的版本信息等。

實體類型(Entity Type)

我們並不限定實體一定是IP、應用或者服務,這取決於實際的業務場景。Nacos有計劃在未來支持不同的實體類型,不過就目前來說,服務發現需要的實體類型是IP。

標簽(Label)

Label是我們抽象出的Entity屬性,Label定義為一個描述Entity屬性的K-V鍵值對。Label的key和value的取值範圍一般都是預先定義好的,當需要對Label進行變更,如增加新的key或者value時,需要調用單獨的介面並觸發相應的事件。一個常見的Label的例子是IP的機房信息,我們認為機房(site)是Label的key,而機房的集合(site1, site2, site3)是Label的value,這個Label的定義就是:site: {site1, site2, site3}。

實體事件(Entity Event)

實體的標簽的變更事件。當CMDB的實體屬性發生變化,需要有一個事件機制來通知所有訂閱方。為了保證實體事件攜帶的變更信息是最新準確的,這個事件里只會包含變更的實體的標識以及變更事件的類型,不會包含變更的標簽的值。

CMDB約定介面

在設計與CMDB交互介面的時候,我們參考了內部對CMDB的訪問介面,並與若幹個外部客戶進行了討論。我們最終確定了以下要求第三方CMDB插件必須實現的介面:

獲取標簽列表

Set<String> getLabelNames();

這個方法將返回CMDB中需要被Nacos識別的標簽名集合,CMDB插件可以按需決定返回什麼標簽個Nacos。不在這個集合的標簽將會被Nacos忽略,即使這個標簽出現在實體的屬性里。我們允許這個集合會在運行時動態變化,Nacos會定時去調用這個介面刷新標簽集合。

獲取實體類型

Set<String> getEntityTypes();

獲取CMDB里的實體的類型集合,不在這個集合的實體類型會被Nacos忽略。服務發現模塊目前需要的實體類似是ip,如果想要通過打通CMDB數據來實現服務的高級負載均衡,請務必在返回集合里包含“ip”。

獲取標簽詳情

Label getLabel(String labelName);

獲取標簽的詳細信息。返回的Label類里包含標簽的名字和標簽值的集合。如果某個實體的這個標簽的值不在標簽值集合里,將會被視為無效。

查詢實體的標簽值

String getLabelValue(String entityName, String entityType, String labelName);
Map<String, String> getLabelValues(String entityName, String entityType);

這裡包含兩個方法,一個是獲取實體某一個標簽名對應的值,一個是獲取實體所有標簽的鍵值對。參數里包含實體的值和實體的類型。註意,這個方法並不會在每次在Nacos內部觸發查詢時去調用,Nacos內部有一個CMDB數據的緩存,只有當這個緩存失效或者不存在時,才會去訪問CMDB插件查詢數據。為了讓CMDB插件的實現儘量簡單,我們在Nacos內部實現了相應的緩存和刷新邏輯。

查詢實體

Map<String, Map<String, Entity>> getAllEntities();
Entity getEntity(String entityName, String entityType);

查詢實體包含兩個方法:查詢所有實體和查詢單個實體。查詢單個實體目前其實就是查詢這個實體的所有標簽,不過我們將這個方法與獲取所有標簽的方法區分開來,因為查詢單個實體方法後面可能會進行擴展,比查詢所有標簽獲取的信息要更多。

查詢所有實體則是一次性將CMDB的所有數據拉取過來,該方法可能會比較消耗性能,無論是對於Nacos還是CMDB。Nacos內部調用該方法的策略是通過可配置的定時任務周期來定時拉取所有數據,在實現該CMDB插件時,也請關註CMDB服務本身的性能,採取合適的策略。

查詢實體事件

List<EntityEvent> getEntityEvents(long timestamp);

這個方法意在獲取最近一段時間內實體的變更消息,增量的去拉取變更的實體。因為Nacos不會實時去訪問CMDB插件查詢實體,需要這個拉取事件的方法來獲取實體的更新。參數里的timestamp為上一次拉取事件的時間,CMDB插件可以選擇使用或者忽略這個參數。

CMDB插件開發流程

參考 https://github.com/nacos-group/nacos-examples,這裡已經給出了一個示例plugin實現。
具體步驟如下:

  1. 新建一個maven工程,引入依賴nacos-api:
    plain <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-api</artifactId> <version>0.7.0</version> </dependency>
  2. 引入打包插件:
    plain <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin>
  3. 定義實現類,繼承com.alibaba.nacos.api.cmdb.CmdbService,並實現相關方法。

  1. 在src/main/resource/目錄下新建目錄:META-INF/services

  1. 在src/main/resources/META-INF/services目錄下新建文件com.alibaba.nacos.api.cmdb.CmdbService,併在文件里將第三步中創建的實現類全名寫入該文件:

  1. 代碼自測完成後,執行命令進行打包:
    plain mvn package assembly:single -Dmaven.test.skip=true
  2. 將target目錄下的包含依賴的jar包上傳到nacos CMDB插件目錄:
    plain {nacos.home}/plugins/cmdb
  3. 在nacos的application.properties里打開載入插件開關:
    plain nacos.cmdb.loadDataAtStart=true
  4. 重啟nacos Server,即可載入到您實現的nacos-cmdb插件獲取您的CMDB數據。

使用Selector實現同機房優先訪問

在拿到CMDB的數據之後,就可以運用CMDB數據的強大威力來實現多種靈活的負載均衡策略了,下麵舉例來說明如何使用CMDB數據和Selector來實現就近訪問。

假設目前Nacos已經通過CMDB拿到了一些IP的機房信息,且它們對應的標簽信息如下:

11.11.11.11
    site: x11

22.22.22.22
    site: x12

33.33.33.33
    site: x11

44.44.44.44
    site: x12

55.55.55.55
    site: x13

11.11.11.11、22.22.22.22、33.33.33.33、44.44.44.44和55.55.55.55.55都包含了標簽site,且它們對應的值分別為x11、x12、x11、x12、x13。我們先註冊一個服務,下麵掛載IP11.11.11.11和22.22.22.22。

圖3 服務詳情

然後我們修改服務的“服務路由類型”,並配置為基於同site優先的服務路由:

圖4 編輯服務路由類型

這裡我們將服務路由類型選擇為標簽,然後輸入標簽的表達式:

CONSUMER.label.site = PROVIDER.label.site

這個表達式的格式和我們抽象的Selector機制有關,具體將會在另外一篇文章中介紹。在這裡您需要記住的就是,任何一個如下格式的表達式:

CONSUMER.label.labelName = PROVIDER.label.labelName

將能夠實現基於同labelName優先的負載均衡策略。

然後假設服務消費者的IP分別為33.33.33.33、44.44.44.44和55.55.55.55,它們在使用如下介面查詢服務實例列表:

naming.selectInstances("nacos.test.1", true)

那麼不同的消費者,將獲取到不同的實例列表。33.33.33.33獲取到11.11.11.11,44.44.44.44將獲取到22.22.22.22,而55.55.55.55將同時獲取到11.11.11.11和22.22.22.22。

以上,便是我們在Nacos中通過打通CMDB,實現就近訪問的實踐。Nacos是阿裡巴巴開源的服務註冊與配置管理產品,參考:《阿裡啟動新項目:Nacos,比 Eureka 更強!》。

本文原創首發於微信公眾號:Java技術棧(id:javastack),關註公眾號在後臺回覆 "架構" 可獲取更多,轉載請原樣保留本信息。


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

-Advertisement-
Play Games
更多相關文章
  • 書接上文,我們繼續開發。 1.界面設計 首先我先用PS設計出如圖1的播放器界面。詳細設計步驟不再表述,這是美工的主要工作,下麵我主要講解一下切圖工作,這部分工作我認為還是自己動手比較合適,美工不知道我們的需求,也不知道怎麼切割符合我們的要求,所以要親自動手。掌握一些圖片設計工具還是十分有必要的 我們 ...
  • 1.JavaScript 語法 JavaScript 是一個腳本語言。 它是一個輕量級,但功能強大的編程語言 2.JavaScript 字面量 在編程語言中,一般固定值稱為字面量,如 3.14。 數字(Number)字面量 可以是整數或者是小數,或者是科學計數(e); 字元串(String)字面量 ...
  • 註:本人小白一個,目前還在校學習,這次老師讓做的項目需要用到這個功能,所以花了一些時間搞了一下,本次案列實現功能為 用戶註冊信息,如果資料庫對應表中存在部分信息,點擊已有的用戶的用戶名,自動補全其它已有的基本信息 實現思路:通過AutoComplete提示,非同步通過用戶名查詢全表,充當AutoCom ...
  • js中this指向是一個難點,花了很長時間來整理和學習相關的知識點。 一、 this this是JS中的關鍵字, 它始終指向了一個對象, this是一個指針; 參考博文: 1. "JavaScript函數中的this四種綁定形式" 2. "this指向及改變this指向的方法" 二、 this顯示綁 ...
  • 為input 添加 readonly=”readonly” UNSELECTABLE="on" 屬性。 IE中設置了readonly=”readonly”,點擊使用日期選擇器時input框中仍然出現了游標,添加 UNSELECTABLE=”on”後,消失。 ...
  • JS實現下拉菜單的功能,實際使用中記得用CSS,性能和代碼都好 ...
  • Datatables是一款jquery表格插件。它是一個高度靈活的工具,可以將任何HTML表格添加高級的交互功能。 官網地址:https://datatables.net/ 中文說明地址:http://www.datatables.club/ 功能說明 分頁,即時搜索和排序幾乎支持任何數據源:DOM ...
  • 界面如圖所示: 要求:在“信息註冊”欄,按下滑鼠,然後滑鼠在頁面移動,在滑鼠移動過程中,該視窗跟著滑鼠移動,當滑鼠鬆開的時候,視窗停止移動。點擊“關閉”,該視窗隱藏。 實現思路: 1.頁面結構分析:一個大盒子d-box來確定位置,裡面放一個小盒子drop(存放“註冊信息(可以拖拽”文字和span標簽 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...