【Spring Cloud】全面解析服務容錯中間件 Sentinel 持久化兩種模式

文章目錄

  • 推送模式
  • 本地文件持久化(拉模式)
    • 配置yml
    • 編寫處理類
    • 添加配置
    • 演示
  • 配置中心持久化(推模式)
    • 修改nacos在sentinel中生效
      • 引入依賴
      • 配置文件
    • 修改sentinel在nacos中生效
      • 下載源碼
      • 更改代碼
      • 演示
  • 總結

推送模式

Sentinel 規則的推送有下面三種模式:
在這里插入圖片描述

通過前面的講解,我們已經知道,可以通過 Dashboard 來為每個 Sentinel 客戶端設置各種各樣的規則,這種屬于原始模式。這種模式存在一個問題,就是這些規則默認是存放在內存中的,極不穩定,所以需要將其持久化。

在這里插入圖片描述

為了達到持久化的目標,我們需要進行改造,改造的方案有兩種:本地文件持久化(拉模式)、配置中心持久化(推模式)

本地文件持久化(拉模式)

拉模式又被稱為 pull 模式,它的數據源(如本地文件、RDBMS等)一般是可寫入的。本地文件數據源會定時輪詢文件的變更,讀取規則。這樣我們既可以在應用本地直接修改文件來更新規則,也可以通過 Sentinel 控制臺推送規則。以本地文件數據源為例,推送過程如下圖所示:

在這里插入圖片描述

首先 Sentinel 控制臺通過API將規則推送至客戶端并更新到內存中,接著注冊的寫數據源會將新的規則保存到本地的文件中。使用 pull模式的數據源時一般不需要對Sentinel控制臺進行改造。這種實現方法好處是簡單,壞處是無法保證監控數據的一致性。

配置yml

#數據庫配置
spring:cloud:sentinel:eager: truetransport:port: 9998 #跟控制臺交流的端口,隨意指定一個未使用的端口即可dashboard: localhost:8080  #指定控制臺服務的地址filter:enabled: false

編寫處理類

實現 InitFunc 接口,在 init 中處理 DataSource 初始化邏輯,并利用 SPI 機制實現加載。

public class FilePersistence implements InitFunc {@Value("${spring.application.name}")private String applicationName;@Overridepublic void init() throws Exception {//創建規則文件String ruleDir = System.getProperty("user.home") + "/sentinel-rules/" + applicationName;String flowRulePath = ruleDir + "/flow-rule.json";String degradeRulePath = ruleDir + "/degrade-rule.json";String systemRulePath = ruleDir + "/system-rule.json";String authorityRulePath = ruleDir + "/authority-rule.json";String paramFlowRulePath = ruleDir + "/param-flow-rule.json";this.mkdirIfNotExits(ruleDir);this.createFileIfNotExits(flowRulePath);this.createFileIfNotExits(degradeRulePath);this.createFileIfNotExits(systemRulePath);this.createFileIfNotExits(authorityRulePath);this.createFileIfNotExits(paramFlowRulePath);//流控規則//創建流控規則的可讀數據源ReadableDataSource<String, List<FlowRule>> flowRuleRDS = new FileRefreshableDataSource<>(flowRulePath,source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>(){}));//將可讀數據源注冊至 FlowRuleManager,這樣當規則文件發生變化時,就會更新規則到內存FlowRuleManager.register2Property(flowRuleRDS.getProperty());WritableDataSource<List<FlowRule>> flowRuleWDS = new FileWritableDataSource<>(flowRulePath,this::encodeJson);//將可寫數據源注冊至 transport 模塊的 WritableDataSourceRegistry 中.//這樣收到控制臺推送的規則時,Sentinel 會先更新到內存,然后將規則寫入到文件中.WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);//降級規則ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(degradeRulePath,source -> JSON.parseObject(source, new TypeReference<List<DegradeRule>>(){}));DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(degradeRulePath,this::encodeJson);WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);//系統規則ReadableDataSource<String, List<SystemRule>> systemRuleRDS= new FileRefreshableDataSource<>(systemRulePath,source -> JSON.parseObject(source, new TypeReference<List<SystemRule>>(){}));SystemRuleManager.register2Property(systemRuleRDS.getProperty());WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(systemRulePath,this::encodeJson);WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);//授權規則ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = new FileRefreshableDataSource<>(authorityRulePath,source-> JSON.parseObject(source, new TypeReference<List<AuthorityRule>>(){}));AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(authorityRulePath, this::encodeJson);WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);//熱點參數規則ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleRDS = new FileRefreshableDataSource<>(paramFlowRulePath,source-> JSON.parseObject(source, new TypeReference<List<ParamFlowRule>>(){}));ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(paramFlowRulePath,this::encodeJson);ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);}
}
  • FileRefreshableDataSource:每次更新規則時自動讀取持久化文件更新到map緩存。
  • FileWritableDataSource:寫數據源,將 sentinel 控制臺發送過來的規則信息寫到持久化文件中。在客戶端的socket接收到規則信息后,更新緩存的時候也會將規則信息寫入文件中持久化。

添加配置

在resources下創建配置目錄 META-INF/services,然后添加文件com.alibaba.csp.sentinel.init.InitFunc,在文件中添加配置類的全路徑it.aq.cheetah.config.FilePersistence

這樣當在 Dashboard 中修改了配置后,Dashboard 會調用客戶端的接口修改客戶端內存中的值,同時將配置寫入文件中,這樣操作的話規則是實時生效的,如果是直接修改文件中的內容,這樣需要等定時任務3秒后執行才能讀到最新的規則。接下來我們演示下:

演示

編寫測試類

@RestController
@RequestMapping("/product2")
@Slf4j
public class ProductController2 {@RequestMapping("/test")@SentinelResource(value = "test")public String test() {return "product2";}
}

啟動項目,發現在目錄下生成了空的規則文件

在這里插入圖片描述
在頁面上增加流控規則

在這里插入圖片描述

然后去看文件flow-rule.json,發現存到了本地文件中

在這里插入圖片描述
接著我們仿照該規則仿寫一個熔斷規則,然后查看網頁數據確實生效了

在這里插入圖片描述

配置中心持久化(推模式)

推模式又叫 Push 模式,它是通過注冊中心實現的,Sentinel控制臺——>配置中心——>Sentinel數據源——>Sentinel
在這里插入圖片描述
用戶不僅可以通過sentinel控制臺進行更新,也可以通過nacos配置中心進行更新,所以在sentinel控制臺或nacos中修改規則后,都需要通知對方刷新最新的配置。

修改nacos在sentinel中生效

引入依賴

我們在之前項目的基礎上引入新的依賴

<!--nacos配置中心-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--以nacos作為sentinel數據源的依賴--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>

配置文件

nacos 配置:因為我們用nacos作為了配置中心,我們可以將sentinel的基本配置放入到nacos中就可以了,所以當前服務的yml配置文件中只需要寫一些基本的配置就可以了。

spring:cloud:nacos:discovery:server-addr: localhost:8848config:server-addr: localhost:8848file-extension: yml

在nacos中配置sentinel信息

spring: cloud:sentinel:transport:# 跟控制臺交流的端口,隨意指定一個未使用的端口即可port: 9998 # 指定控制臺服務的地址dashboard: localhost:8080  # sentinel用nacos作為數據源的配置datasource: #流控管理(這個名稱可以自定義)flow-control: # 告訴sentinel用nacos作為數據源nacos: # 配置中心里執行文件的 dataIddataId: shop-product-flow.json  # nacos的地址serverAddr: 127.0.0.1:8848 # 指定文件配置的是哪種規則rule-type: flow

注意:如果使用的 namespace 不是默認的,記得配置 namespace 參數。

  • dataId:需要告訴 sentinel 讀取配置中心中的哪個配置文件;
  • rule-type:告訴 sentinel 配置文件配置的控制規則,flow:流控、degrade:熔斷、param-flow 熱點參數,想看有哪些規則參數可以查看com.alibaba.cloud.sentinel.datasource包下的枚舉類:RuleType。
public enum RuleType {/*** flow.*/FLOW("flow", FlowRule.class),/*** degrade.*/DEGRADE("degrade", DegradeRule.class),/*** param flow.*/PARAM_FLOW("param-flow", ParamFlowRule.class),/*** system.*/SYSTEM("system", SystemRule.class),/*** authority.*/AUTHORITY("authority", AuthorityRule.class),/*** gateway flow.*/GW_FLOW("gw-flow","com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule"),/*** api.*/GW_API_GROUP("gw-api-group","com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition");

shop-product-flow.json文件中配置【流控規則】

[{"clusterConfig": {"acquireRefuseStrategy": 0,"clientOfflineTime": 2000,"fallbackToLocalWhenFail": true,"resourceTimeout": 2000,"resourceTimeoutStrategy": 0,"sampleCount": 10,"strategy": 0,"thresholdType": 0,"windowIntervalMs": 1000},"clusterMode": false,"controlBehavior": 0,"count": 10.0,"grade": 1,"limitApp": "default","maxQueueingTimeMs": 500,"resource": "/product2/test","strategy": 0,"warmUpPeriodSec": 10}
]

在這里插入圖片描述

然后去 dashboard 中查看,發現流控規則已經在控制中顯示了

在這里插入圖片描述
目前我們已經實現了在 nacos 中配置的文件直接在sentinel dashboard中生效,但是我們在sentinel dashboard中修改了配置,nacos 是不會監聽到并進行修改的。接下來我們實現一下通過 sentinel 控制臺設置的規則直接持久化到 nacos配置中心。

修改sentinel在nacos中生效

Sentinel 控制臺提供 DynamicRulePublisherDynamicRuleProvider 接口用于實現應用維度的規則推送和拉取。

下載源碼

https://github.com/alibaba/Sentinel/releases下載dashboard的代碼源碼。

在這里插入圖片描述

解壓之后打開sentinel-dashboard項目,將 pom.xml 文件中作用域為 test 的注釋掉,注釋掉后默認的作用域為 compile。

  • test:作用域表示該依賴項只在測試時有用,在編譯和運行時不會被用到。
  • compile:作用域范圍的依賴項在所有情況下都是有效的,包括編譯、運行和測試。

把 test 包下的兩個類復制過來

在這里插入圖片描述

  • NacosConfigUtil 類主要就是 nacos 配置的規則,比如配置文件的后綴,分組Group_ID等等。因為我用的分組是默認分組,所以改為DEFAULT_GROUP,我之前的規則文件是shop-product-flow.json,所以我把規則文件后綴FLOW_DATA_ID_POSTFIX改為"-flow.json"。
  • NacosConfig類是為了注入nacos的信息以及轉換器類。

更改代碼

application.properties 中增加 nacos 的配置

# nacos 配置
nacos.serverAddr=localhost:8848
nacos.username=nacos
nacos.password=nacos

NacosConfig 修改為從配置文件中獲取nacos配置

 @Beanpublic ConfigService nacosConfigService() throws Exception {Properties properties = new Properties();//Nacos地址properties.put("serverAddr", serverAddr);//Nacos用戶名properties.put("username", username);//Nacos密碼properties.put("password", password);return ConfigFactory.createConfigService(properties);}

com.alibaba.csp.sentinel.dashboard.rule.FlowRuleApiPublisher#publish方法中增加推送到nacos的邏輯代碼

//將規則推送到nacos
configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, converter.convert(rules));

com.alibaba.csp.sentinel.dashboard.rule.FlowRuleApiProvider#getRules方法中修改為從nacos中讀取配置的邏輯

@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {String rules = configService.getConfig(appName + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,NacosConfigUtil.GROUP_ID, 3000);if (StringUtil.isEmpty(rules)) {return new ArrayList<>();}return converter.convert(rules);
}

改造流控的controller類FlowControllerV1,將配置保存到內存中的邏輯改為保存到nacos中

@Autowired
@Qualifier("flowRuleDefaultProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;@Autowired
@Qualifier("flowRuleDefaultPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;@GetMapping("/rules")
@AuthAction(PrivilegeType.READ_RULE)
public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app,@RequestParam String ip,@RequestParam Integer port) {......try {
//            List<FlowRuleEntity> rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);//從nacos中讀取規則List<FlowRuleEntity> rules = ruleProvider.getRules(app);rules = repository.saveAll(rules);return Result.ofSuccess(rules);} catch (Throwable throwable) {logger.error("Error when querying flow rules", throwable);return Result.ofThrowable(-1, throwable);}
}private void publishRules(String app, String ip, Integer port) throws Exception {//將規則推送到nacosList<FlowRuleEntity> rules = repository.findAllByApp(app);rulePublisher.publish(app, rules);//        List<FlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
//        return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules);
}//其余調用publishRules方法的地方做下簡單調整

演示

啟動當前項目,流控規則中存在我們之前在nacos中創建的文件,我們將原來的單機閾值從10改為12,然后保存。查看nacos中配置文件的數據,發現已經生效了。

在這里插入圖片描述
至于其他規則,大家可以自行實現,此處就不一一實現了

在這里插入圖片描述

總結

到這兒,服務容錯中間件Sentinel的兩種持久化模式就已經介紹完了。下一篇將為大家帶來Feign整合容錯組件 Sentinel 的文章,敬請期待吧!

后續的文章,我們將繼續完善我們的微服務系統,集成更多的Alibaba組件。想要了解更多JAVA后端知識,請點擊文末名片與我交流吧。留下您的一鍵三連,讓我們在這個寒冷的東西互相溫暖吧!

參考鏈接:

  • https://blog.csdn.net/weixin_36279234/article/details/130922604;
  • https://blog.csdn.net/u022812849/article/details/131206976;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/14631.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/14631.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/14631.shtml

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

相關文章

allegro 無法刪除Xnet

allegro 無法刪除Xnet Orcad中打開Constraint Manager之后&#xff0c;再生成網表&#xff0c;導入PCB后就會出現一堆Xnet網絡。無法去除Xnet。 解決辦法 在原理圖ORCAD中&#xff0c; 1、打開Edit Object properties 2、選擇Filter by:Capture 3、點擊New Property 4、設置…

火山引擎邊緣云亮相 Force 原動力大會,探索 AI 應用新范式

5月15日&#xff0c;2024 春季火山引擎 FORCE 原動力大會在北京正式舉辦。大會聚焦 AI 主題&#xff0c;以大模型應用為核心、以 AI 落地為導向&#xff0c;展示了火山引擎在大模型、云計算領域的實踐應用&#xff0c;攜手汽車、手機終端、金融、消費、互聯網等領域的專家和企業…

2024042102-array-list

數組 Array 一、前言 數組是數據結構還是數據類型&#xff1f; 數組只是個名稱&#xff0c;它可以描述一組操作&#xff0c;也可以命名這組操作。數組的數據操作&#xff0c;是通過 idx->val 的方式來處理。它不是具體要求內存上要存儲著連續的數據才叫數據&#xff0c;而…

js積累三(web頁面一段時間未操作,退出登錄)

//核心代碼&#xff0c;已封裝function CountDownLogout() {/* if 30 seconds no operation then logout */var maxTime 30; // seconds&#xff0c;可自行修改時長var time_time maxTime;/* 鼠標點擊事件 */$(document).mousedown(function(){time_time maxTime; //…

Spring Aop對本地事務的影響

1.Transactional聲明式事物也是基于aop實現的&#xff0c;public方法加了Transactional注解后&#xff0c;已經成功的創建了事務&#xff0c;但是當前方法仍在方法攔截器中 2.業務方法發生異常之后的處理 判斷回滾條件&#xff1a; 如果自定義了RollbackRuleAttribute列表&am…

EI會議的最佳論文獎是什么?如何申請?

EI會議的最佳論文獎通常是指在EI&#xff08;工程索引&#xff0c;Engineering Index&#xff09;收錄的學術會議中&#xff0c;評選出的表現最優秀的論文獎項。以下是關于該獎項的一些基本信息及申請步驟&#xff1a; 最佳論文獎的含義 評選標準&#xff1a;最佳論文獎通常基…

多線程、進程、線程五種狀態、synchronized、volatile、Lock、CAS、死鎖、ThreadLocal

1、并發編程 并發編程三要素 原子性&#xff1a;只一個操作要么全部成功&#xff0c;要么全部失敗可見性&#xff1a;一個線程對共享變量的修改&#xff0c;其他線程能夠立刻看到有序性&#xff1a;程序執行的順序按照代碼的先后順序執行 synchronized&#xff0c;Lock解決原…

前端vue 動態加載ts文件,動態調用ts內的方法

業務場景: 在某個業務場景中, 我們需要在數據庫配置ts文件路徑,和需要調用的函數名稱, 前端需要再指定的場景下,觸發對應的函數, 并執行處理邏輯,返回結果. 實現: 這是一個數據庫配置生成的動態表單 動態校驗的例子, 需要引用動態的函數校驗 任意一個js文件, common1.ts c…

大模型日報|今日必讀的 13 篇大模型論文

大家好&#xff0c;今日必讀的大模型論文來啦&#xff01; 1.MIT新研究&#xff1a;并非所有語言模型特征都是線性的 最近的研究提出了線性表征假說&#xff1a;語言模型通過操作激活空間中概念&#xff08;“特征”&#xff09;的一維表征來執行計算。與此相反&#xff0c;來…

CHI dataless 傳輸——CHI(4)

上篇介紹了read的操作類型&#xff0c;本篇我們來介紹一下dataless 目錄 一、dataless操作概覽 二、Non-CMO (Non-Cache Maintenance Operation) 1、CleanUnique 2、StashOnce and StashOnceSep 3、Evict 三、CMO (Cache Maintenance Operation) 一、dataless操作概覽 名…

C# 中的 Dictionary<TKey, TValue> 類

Dictionary<TKey, TValue> 是 C# 中的一個泛型集合類,它提供了一種鍵值對的存儲結構,可以用來存儲和快速訪問數據。它的主要特點如下: 鍵值對結構: Dictionary 中的每個元素都是一個鍵值對,鍵必須是唯一的,值可以重復。 快速訪問: Dictionary 基于哈希表實現,可以提供 O…

大白話聊聊MySQL查詢之五子句(知識簡單但重要)

前言&#xff1a; 在日常開發中&#xff0c;查詢數據占很大的比重&#xff0c;在使用 MySQL 數據庫進行查詢時&#xff0c;我們經常需要通過各種條件和規則來篩選和排序數據。要實現這些功能&#xff0c;就不得不使用以下這些子句&#xff1a;WHERE、ORDER BY、GROUP BY、HAVI…

物聯網層次架構設計

物聯網可以分為三個層次&#xff0c;底層是用來感知數據的感知層&#xff0c;即利用傳感器、二維碼、RFID等設備隨時隨地獲取物體的信息。第二層是數據傳輸處理的網絡層&#xff0c;即通過各種傳感網絡與互聯網的融合&#xff0c;將對象當前的信息實時準確地傳遞出去。第三層則…

忍の摸頭之術游戲娛樂源碼

本資源提供給大家學習及參考研究借鑒美工之用&#xff0c;請勿用于商業和非法用途&#xff0c;無任何技術支持&#xff01; 忍の摸頭之術游戲娛樂源碼&#xff0c;抖音上面非常火的摸頭殺畫面,看得我眼花繚亂,源碼拿去玩吧&#xff1b; 目錄說明 忍の摸頭之術&#xff1a;域…

輕松同步:將照片從三星手機傳輸到iPad的簡便方法

概括 想要在新 iPad 上查看三星照片嗎&#xff1f;但是&#xff0c;如果您不知道如何將照片從三星手機傳輸到 iPad&#xff0c;則無法在 iPad 上查看圖片。為此&#xff0c;本文分享了 7 個有用的方法&#xff0c;以便您可以使用它們在不同操作系統之間輕松發送照片。現在&…

EfficientSAM分割對象后求其中圖像中的高

1 分割對象 EfficientSAM https://github.com/yformer/EfficientSAM 2 計算在圖像中最高點即y值最小點 import os import cv2def read_images(folder_path):image_files [f for f in os.listdir(folder_path) iff.endswith(".jpg") or f.endswith(".png&quo…

c語言之運算符練習題

C語言中的運算符是執行特定操作的符號&#xff0c;它們是編程中不可或缺的部分。C語言提供了多種類型的運算符&#xff0c;包括算術運算符、關系運算符、邏輯運算符、位運算符、賦值運算符等。以下是一些常見的C語言運算符練習題&#xff0c;可以幫助你熟悉和練習這些運算符的使…

虛擬化技術[1]之服務器虛擬化

文章目錄 虛擬化技術簡介數據中心虛擬化 服務器虛擬化服務器虛擬化層次寄居虛擬化裸機虛擬化VMM無法直接捕獲特權指令解決方案 服務器虛擬化底層實現CPU虛擬化內存虛擬化I/O設備虛擬化 虛擬機遷移虛擬機動態遷移遷移內容&#xff1a;內存遷移遷移內容&#xff1a;網絡資源遷移遷…

小短片創作-組裝場景(一)

1、項目基礎設置 通過第三人稱模板&#xff0c;創建1個項目 1.自動曝光&#xff1a;關閉&#xff0c;因為要做專業的小短片&#xff0c;曝光需要手動控制。 2.擴展自動曝光中的默認亮度范圍&#xff1a;啟用 3.全局光照系統&#xff1a;選擇屏幕空間光照&#xff08;SSGI&am…

Transformer詳解常見面試問題

文章目錄 1. 各模塊解決1.1 輸入部分1.2 多頭注意力&#xff08;作者使用8個頭&#xff09;1.3 殘差和LayerNorm1.4 Decoder部分 2.Transformer經典問題2.1 tranformer為何使用多頭注意力機制&#xff1f;2.2 Transformer相比CNN的優缺點2.3 Encoder和decoder的區別&#xff1f…