作積極的人,越努力越幸運!
在介紹集羣限流以前須要首先掌握動態數據源的配置方式,本文將根據 Sentinel 官方提供的代碼提出總體架構思路,並最終給出實踐指導。redis
舒適提示:本文主要分爲動態數據源架構設計理念、從官方示例尋找改造思路、基於SpringBoot改造方案三個部分來詳細剖析 Sentienl 動態數據源的改造方案,按部就班,不只解決問題自己,更是反映了做者研究一個問題的思路與方法。spring
在 Sentinel 中主要有以下幾個角色:管理後臺、限流熔斷規則數據源、應用程序。數據庫
1)管理後臺編程
管理後臺主要用於可視化配置限流規則、熔斷規則,其操做界面截圖以下:json
2)限流熔斷規則數據源
用於存儲限流熔斷規則的數據容器,在 Sentinel 中對應動態數據源這個概念,動態數據源包含兩層含義:架構
數據容器
數據容器指的就是存儲熔斷、限流等規則配置的數據庫,例如關係型數據庫、Zookeeper等等,在實際生產過程當中須要選用支持持久化功能的數據庫,不然程序一重啓,配置規則就會丟失,顯然是不能接受的。app
但願經過 Sentinel 提供的限流、熔斷功能對應用程序加以保護,須要引用 Sentinel 相關的 SDK,根據採集的調用信息判斷當前是否符合限流規則。ide
後臺管理系統、動態數據源、應用程序的關係如圖所示:測試
從官方的文檔中能夠明確獲悉 sentinel-dashboard 即官方自帶的後臺管理系統只支持將限流、熔斷等限流配置規則存儲在內存中,一旦後臺管理系統重啓,配置的熔斷規則將所有丟失,因此在生產實踐過程當中須要對 sentinel-dashboard 進行必定的改造,引入動態數據源,例如 Zookeeper,對限流等配置進行持久化存儲。架構設計
有了上面的架構設計理念爲咱們的改造提供了方向,那如何具體改造呢?首先咱們來看一下官方提供的 Demo 程序。官方提供的示例代碼以下圖所示:
接下來咱們將以 zookeeper 動態數據源來介紹基於 zookeeper 如何構建 Sentinel 動態數據源。
首先查閱一下 ZookeeperConfigSender,該類主要的做用是將配置寫入到 zookeeper 中,其關鍵代碼截圖以下:
這個類的測試目的很簡單,先將限流規則持久化到 Zookeeper 中,充當的角色與 sentinel-dashboard 的角色一致,故這個類爲咱們改造後臺管理系統帶來很大的啓發,便可以經過 zookeeper 存儲 sentinel 限流規則,從 demo 示例能夠看出限流規則在 zookeeper 中的目錄結構,路徑爲 /{groupId} / {dataid} ,該節點的 value 值存儲 json 字符串,存儲全部的限流規則。
實踐指導,一般基於 zookeeper 的開發,主要是規劃好目錄結構,關於 Sentinel,我對給出一個初步的目錄規劃。
在 zookeeper 中建立一個根節點,例如 /sentienl 用來表示限流相關的根目錄。
實現存儲規則的配置存儲後接下來是須要客戶端能動態感知規則的變化,從而是配置規則實時生效。
咱們依然先來看一下官方示例,其核心代碼如圖所示:
這裏儘管引入 groupId 與 dataId 的概念是方便與 nacos 進行切換,但就算不切換,基於 zookeeper 的編程,這種目錄規劃是很是有必要的。上面的示例代碼有兩個關鍵點:
客戶端在啓動的時候會調用 FlowRuleManager 相關方法加載限流相關的配置,那若是配置規則發生變化後,客戶端如何動態感知呢?其關鍵就在於 ZookeeperDataSource 的實現中,其實現關鍵點以下:
即在構建 ZookeeperDataSource 時會監聽 /groupId/dataId 節點,即存放限流配置的節點,一旦數據發生變化,就會通知到客戶端,從而調用 loadConfig 從新更新Sentienl 客戶端的限流配置,從而實現配置實時生效。
從官方的示例中咱們不難發現,引入 Zookeeper 數據源主要有兩個步驟:將數據存儲在Zookeeper中以及在客戶端監聽ZK從而實時生效兩個步驟。
sentinel 官方提供了默認的後臺管理系統實現:sentinel-dashboard,但其缺點很是明顯:基於內存存儲,沒法用於實際生產過程。你們可能會向後臺管理系統將配置信息存儲在內存中,那接入的客戶端如何從 sentinel-dashboard 的內存中獲取配置信息呢,這是由於 sentinel-dashboard 裏提供了簡單的機器發現,而且內置了 sentinel 客戶端之間、sentinel 客戶端與 sentinel-dashboard 之間的通信協議,具體由 sentinel-transport 模塊實現,目前提供了基於 http 與 netty 的實現方式,故能將 sentinel-dashboard 內存中的配置信息推送到客戶端,從而使客戶端根據配置進行限流與熔斷。
接下來回答本文的重點部分,基於 sentinel-dashboard 如何引入 zookeeper 等動態數據源呢?
首先咱們能夠順着 sentinel-dashboard 的提供的控制器,尋找其後臺入口,改造目標也很明確,就是將數據持久化到 zookeeper中,例如增長流控規則的後臺處理入口爲:
只須要從這裏開始改造,將其配置持久化到數據庫中和 zookeeper中便可。將數據存儲在 zookeeper 中,其關鍵是設計好各個項目如何有組織有條理的在 zookeeper 中進行組織。我給出以下設計方案:
這樣相關管理人員能夠直接在 sentinel-dashboard 中配置限流規則,即按照應用爲維度進行存儲,每個應用再按照維度,例如限流、熔斷、熱點、集羣等維度進行配置,每一分類節點的值存儲的是全部的配置,使用 [{},{}] 這種JSON格式進行存儲。
目前大部分項目都是基於 SpringBoot,故本文給出基於 SpringBoot 進行的客戶端加載實現思路。
利用 SpringBoot 的事件機制,在 Spring 容器初始化後,開始加載 zookeeper 中的配置,其實現思路是讀取 zookeeper 中的 /sentinel 下全部的子節點,而後並依次遍歷其子節點(appid),而後依次讀取 flow(限流)、degrade(熔斷)等配置,並調用 Sentinel 的 相關API完成加載,其僞代碼以下:
其主要關鍵點以下:
歡迎加入個人知識星球,一塊兒交流源碼,探討架構,揭祕億級訂單的架構設計與實踐經驗,打造高質量的技術交流圈,爲廣大星友提供高質量問答服務,長按以下二維碼加入。