微服務雪崩防護最佳實踐之sentinel

思考

1、當服務訪問量達到一定程度,流量扛不住的時候,該如何處理?

2、服務之間相互依賴,當服務A出現響應時間過長,影響到服務B的響應,進而產生連鎖反應,直至影響整個依賴鏈上的所有服務,該如何處理?

這是分布式、微服務開發不可避免的問題。

我們系統假如是這樣的調用圖。當G服務出現程序Bug,大流量請求,硬件故障,緩存擊穿時,導致服務不可用。進而導致D服務不可用,導致A服務不可用。

B、C、D三個服務共享A服務的線程池,當D服務出現故障時,則導致A服務中所有線程池都在等待D服務響應而被阻塞。進而導致A服務不可用

?解決方案

超時機制

在不做任何處理的情況下,服務提供者不可用會導致消費者請求線程強制等待,而造成系統資源耗盡。加入超時機制,一旦超時,就釋放資源。由于釋放資源速度較快,一定程度上可以抑制資源耗盡的問題。

服務限流(資源隔離)

限制請求核心服務提供者的流量,使大流量攔截在核心服務之外,這樣可以更好的保證核心服務提供者不出問題,對于一些出問題的服務可以限制流量訪問,只分配固定線程資源訪問,這樣能使整體的資源不至于被出問題的服務耗盡,進而整個系統雪崩。那么服務之間怎么限流,怎么資源隔離?例如可以通過線程池+隊列的方式,通過信號量的方式。

當D服務出問題時,A調用C服務和B服務不受影響。

服務熔斷

遠程服務不穩定或網絡抖動時暫時關閉,就叫服務熔斷。

服務降級

有服務熔斷,必然要有服務降級。

sentinel開源功能不足之點

?相信用過開源版本sentinel的小伙伴,會發現當服務重新啟動是,sentinel控制臺規則數據則失效;接下里引入sentinel-datasource-nacos 規則持久化,來解決sentinel規則失效問題。但是發現在sentinel的dashboard的客戶端更改規則生效,但是nacos中的配置未發生變更,導致dashboard的和nacos的數據不一致現象。

?

紅色的箭頭未實現,就會導致dashboard配置的規則和nacos配置中的數據不一致。

為了解決這個問題,官方的建議是在dashboard源碼中進行改造,直接寫入數據到nacos中。標紅的部分

所以實現dashboard和nacos中的數據規則一致,則有兩個方案:

?方案一 需要在應用服務端進行改造

方案二 需要在dashboard的源碼中進行改造(官方推薦

設計模式的核心理念邏輯之一:開放封閉原則。選擇方案一比較好點。

我對方案一進行的實現。

代碼實現

1.SpringContextHolder 工具類(為了能獲取到配置中變量)

@Component
public class SpringContextHolder implements ApplicationContextAware {private static ApplicationContext context;public static ApplicationContext getContext() {return context;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) {context = applicationContext;}
}

2.?SentinelNacosProperties 實體類

public class SentinelNacosProperties {public String serverAddr;public String groupId;public String dataId;public String username;public String password;public String namespace;public String appName;
//自己添加get/set方法
}

?3.利用sentinel的擴展點InitFunc(NacosDataSourceInitFunc)

@Slf4j
public class NacosDataSourceInitFunc implements InitFunc {@Overridepublic void init() throws Exception {log.info("NacosDataSourceInitFunc init...");Environment env = SpringContextHolder.getContext().getEnvironment();String appName = env.getProperty("spring.application.name", "demo-project");String groupId = "SENTINEL_GROUP";String serverAddr = env.getProperty("spring.cloud.nacos.config.server-addr", "localhost:8848");String namespace = env.getProperty("spring.cloud.nacos.config.namespace", "public");String username = env.getProperty("spring.cloud.nacos.config.username", "nacos");String password = env.getProperty("spring.cloud.nacos.config.password", "xx#pj70Qdd1");log.info("NacosDataSourceInitFunc appName:{}, group:{}, serverAddr:{}", appName, groupId, serverAddr);SentinelNacosProperties sentinelNacosProperties = new SentinelNacosProperties();sentinelNacosProperties.setAppName(appName);sentinelNacosProperties.setGroupId(groupId);sentinelNacosProperties.setServerAddr(serverAddr);sentinelNacosProperties.setNamespace(namespace);sentinelNacosProperties.setUsername(username);sentinelNacosProperties.setPassword(password);// =============== FlowRule 流控規則 ==================String flowDataId = appName + "-flow-rules";sentinelNacosProperties.setDataId(flowDataId);WritableDataSource<List<FlowRule>> flowRuleWritableDataSource = new NacosWritableDataSource<>(sentinelNacosProperties, JSON::toJSONString);WritableDataSourceRegistry.registerFlowDataSource(flowRuleWritableDataSource);// =============== DegradeRule 降級規則 ==================String degradeDataId = appName + "-degrade-rules";sentinelNacosProperties.setDataId(degradeDataId);WritableDataSource<List<DegradeRule>> degradeRuleWritableDataSource = new NacosWritableDataSource<>(sentinelNacosProperties, JSON::toJSONString);WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWritableDataSource);// =============== AuthorityRule 授權規則 ==================String authorityDataId = appName + "-authority-rules";sentinelNacosProperties.setDataId(authorityDataId);WritableDataSource<List<AuthorityRule>> authorityRuleWritableDataSource = new NacosWritableDataSource<>(sentinelNacosProperties, JSON::toJSONString);WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWritableDataSource);// =============== SystemRule 系統規則 ==================String systemDataId = appName + "-system-rules";sentinelNacosProperties.setDataId(systemDataId);WritableDataSource<List<SystemRule>> systemRuleWritableDataSource = new NacosWritableDataSource<>(sentinelNacosProperties, JSON::toJSONString);WritableDataSourceRegistry.registerSystemDataSource(systemRuleWritableDataSource);log.info("NacosDataSourceInitFunc init finished");}
}

由于sentinel的各個規則都可以在不同的nacos服務上,根據自己的修改此配置。

4. 寫數據源的實現

import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.WritableDataSource;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.beans.factory.annotation.Value;import java.util.Properties;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** Sentinel nacos寫數據源實現**/
public class NacosWritableDataSource<T> implements WritableDataSource<T> {private final String serverAddr;private final String groupId;private final String dataId;private final String username;private final String password;private final String namespace;private final Properties properties;private ConfigService configService;private final Converter<T, String> configEncoder;private final Lock lock = new ReentrantLock(true);public NacosWritableDataSource(SentinelNacosProperties nacosProperties, Converter<T, String> configEncoder) {this.serverAddr = nacosProperties.getServerAddr();this.namespace = nacosProperties.getNamespace();this.groupId = nacosProperties.getGroupId();this.dataId = nacosProperties.getDataId();this.username = nacosProperties.getUsername();this.password = nacosProperties.getPassword();this.properties = NacosWritableDataSource.buildProperties( nacosProperties);this.configEncoder = configEncoder;initConfigService();}private void initConfigService() {try {this.configService = NacosFactory.createConfigService(properties);} catch (NacosException e) {e.printStackTrace();}}private static Properties buildProperties(SentinelNacosProperties nacosProperties) {Properties properties = new Properties();properties.setProperty(PropertyKeyConst.SERVER_ADDR, nacosProperties.getServerAddr());properties.setProperty(PropertyKeyConst.NAMESPACE, nacosProperties.getNamespace());properties.setProperty(PropertyKeyConst.USERNAME, nacosProperties.getUsername());properties.setProperty(PropertyKeyConst.PASSWORD, nacosProperties.getPassword());return properties;}@Overridepublic void write(T t) throws Exception {lock.lock();try {configService.publishConfig(dataId, groupId, this.configEncoder.convert(t));} finally {lock.unlock();}}@Overridepublic void close() throws Exception {}}

5. application.yml 規則定義

spring:cloud:sentinel:transport:dashboard: localhost:8080 # Sentinel 控制臺地址port: 8719 # 本地啟動的端口,用于與 Sentinel 控制臺通信eager: true # 是否立即初始化web-context-unify: false # 是否合并 Web 上下文datasource:flow-rules:nacos:server-addr: 127.0.0.1:8848dataId: ${spring.application.name}-flow-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: flowdegrade-rules:nacos:server-addr: 127.0.0.1:8848dataId: ${spring.application.name}-degrade-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: degradeparam-flow-rules:nacos:server-addr: 127.0.0.1:8848dataId: ${spring.application.name}-param-flow-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: param-flowauthority-rules:nacos:server-addr: 127.0.0.1:8848dataId: ${spring.application.name}-authority-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: authoritysystem-rules:nacos:server-addr: 127.0.0.1:8848dataId: ${spring.application.name}-system-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: system

nacos的配置自己添加一下即可。

5.由于我們利用的sentinel的SPI機制

需要以下的文件夾META-INF/services/

com.alibaba.csp.sentinel.init.InitExecutor的類

?將你的實現類按照圖中存放即可。

?測試

nacos中流控規則中的閾值是33.

dashboard的界面顯示也是33.則代表nacos->服務內存->dashboard 這條鏈路已經走通。?

?現在我們在dashboard上進行修改閾值為:55

查看naocs是否同步修改:

?

nacos中已經修改,則代表方案一已實現。

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

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

相關文章

阿里云監控及運維常見問題

云監控介紹&#xff1a;阿里云的云監控服務&#xff08;CloudMonitor&#xff09;是一款簡單易用、功能強大的監控工具&#xff0c;主要用來幫助用戶實時監控阿里 云上的各種資源&#xff08;比如服務器、數據庫、網絡等&#xff09;&#xff0c;并在出現問題時及時發出警報&am…

深入解析 vLLM 分布式推理與部署策略

在當今人工智能快速發展的時代&#xff0c;大型語言模型&#xff08;LLM&#xff09;的推理和部署面臨著諸多挑戰&#xff0c;尤其是當模型規模日益龐大時&#xff0c;如何高效地利用硬件資源成為關鍵問題。vLLM 作為一種強大的工具&#xff0c;為分布式推理和部署提供了多種策…

PostgreSQL 終端命令詳解及實際應用案例

PostgreSQL 作為一款功能強大的開源關系型數據庫&#xff0c;其終端命令是數據庫管理員、開發人員日常操作的核心工具。這些命令覆蓋數據庫連接、對象管理、數據操作、備份恢復、權限控制等多個維度&#xff0c;掌握其實際應用場景能顯著提升工作效率。本文結合不同行業的實操案…

步進電機基礎

1、ENABLE ̄\overline{ENABLE}ENABLE 的意思&#xff1a; ENABLE上面的橫線表示這是一個低電平有效的信號&#xff1a;當ENABLE信號為低電平&#xff08;0V或邏輯0&#xff09;時&#xff0c;芯片被使能&#xff08;激活&#xff09;當ENABLE信號為高電平&#xff08;VDD或邏輯…

Redis進階--緩存

目錄 一、引言 二、介紹 1.為什么Mysql的速度慢呢&#xff1f; 2.緩存更新策略 1.定期生成 2.實時生成 3.redis的內存淘汰機制 4.注意事項 1.緩存預熱 2.緩存穿透 3.緩存擊穿 4.緩存雪崩 三、總結 一、引言 本篇文章將介紹Redis其中一個重要的作用&#xff0c;作為…

微軟原版系統下載的幾個好用網站

“不要因為走得太遠&#xff0c;而忘記為什么出發。” 愿每一位Windows用戶&#xff0c;都能在這份情懷中找到屬于自己的小確幸&#xff01;滿滿的情懷&#xff01; 微軟官方渠道 微軟官網提供純凈的ISO鏡像下載&#xff0c;適用于Windows 10/11等系統。訪問Microsoft官網下…

kotlin Flow快速學習2025

其實&#xff0c;第一章節&#xff0c;只是讓你了解下Flow的基本情況。我們開發中&#xff0c;基本很少使用這種模式。所以來講&#xff0c;我們甚至可以直接使用StateFlow和SharedFlow才是正途。這是很多教程沒有說明的點。所以第一章隨便瀏覽下即可。日后再補充理解都是可以的…

【人工智能99問】什么是教師強制?(16/99)

文章目錄什么是教師強制&#xff1f;教師強制&#xff08;Teacher Forcing&#xff09;的定義原比例&#xff08;Original Proportion&#xff09;教師強制的舉例說明&#xff08;一&#xff09;教師強制的舉例說明&#xff08;二&#xff09;優點和缺點解決曝光偏差的方法什么…

【WPF】WPF 自定義控件之依賴屬性

&#x1f4e6; WPF 自定義控件之依賴屬性 在開發 WPF 應用時&#xff0c;自定義控件能幫助我們復用邏輯和樣式&#xff0c;但我很快會遇到一個問題&#xff1a;在控件內部如何支持數據綁定和屬性變更通知&#xff1f;特別是我們繼承自 Control 的時候&#xff0c;已經不能再繼承…

DOM型XSS破壞

目錄 首先 然后 第一種 第二種&#xff08;DOM&#xff09; HTMLCollection HTML Relationships Custom 解 首先 <script>//urlencode解碼 //location接口的hash屬性是一個字符串&#xff0c;包含一個“#”后跟位置URL的片段標識符。如果URL沒有片段標識符&#…

Linux C 多線程基本操作

我們已經了解進程的基本概念&#xff1a;進程是正在執行的程序&#xff0c;并且是系統資源分配的基本單位。當用戶需要在一臺計算機上去完成多個獨立的工作任務時&#xff0c;可以使用多進程的方式&#xff0c;為每個獨立的工作任務分配一個進程。多進程的管理則由操作系統負責…

C語言基礎:二維數組練習題

1. 一個二維數組賦了初值&#xff0c;用戶輸入一個數&#xff0c;在該二維數組中查找。找到則返回行列位置&#xff0c;沒找到則提示。#include <stdio.h>int main() {int arr[3][3] {{1, 2, 3},{4, 5, 6},{7, 8, 9}};int t;printf("要查找的數&#xff1a;")…

Java面試題034:一文深入了解MySQL(6)

Java面試題029&#xff1a;一文深入了解MySQL&#xff08;1&#xff09; Java面試題030&#xff1a;一文深入了解MySQL&#xff08;2&#xff09; Java面試題031&#xff1a;一文深入了解MySQL&#xff08;3&#xff09; Java面試題032&#xff1a;一文深入了解MySQL&#x…

Java基礎教程(011):面向對象中的構造方法

10-面向對象-構造方法 構造方法也叫做構造器、構造函數。 作用&#xff1a;在創建對象的時候給成員變量進行初始化的。 ? 一、構造方法的特點特點說明與類同名構造方法的名稱必須與類名相同沒有返回類型構造方法沒有返回值&#xff0c;甚至不能寫 void自動調用使用 new 創建對…

Adobe Photoshop:數字圖像處理的終極工具指南

Hi&#xff0c;我是布蘭妮甜 &#xff01;Adobe Photoshop自1990年問世以來&#xff0c;已經成為數字圖像處理領域的標桿和代名詞。這款強大的軟件不僅徹底改變了攝影、設計和藝術創作的方式&#xff0c;還深刻影響了我們消費和感知視覺內容的文化方式。從專業攝影師到社交媒體…

本期來講講什么是LVS集群?

集群和分布式 集群&#xff08;Cluster&#xff09;&#xff0c;解決某個問題將多臺計算機組合形成的系統群。 常見的集群類型&#xff1a; 負載均衡(LoadBalancing&#xff0c;簡稱LB)&#xff1a;由多個相同配置的主機組成&#xff0c;每個主機經過調度承擔部分訪問&#…

JVM 類加載過程筆記

一、概述 JVM&#xff08;Java Virtual Machine&#xff09;在運行 Java 程序時&#xff0c;需要將 .class 字節碼文件加載到內存中&#xff0c;并轉換成可以被 JVM 執行的數據結構&#xff0c;這一過程就是 類加載過程&#xff08;Class Loading Process&#xff09;。 JVM 的…

基于爬蟲技術的電影數據可視化系統 Python+Django+Vue.js

本文項目編號 25002 &#xff0c;文末自助獲取源碼 \color{red}{25002&#xff0c;文末自助獲取源碼} 25002&#xff0c;文末自助獲取源碼 目錄 一、系統介紹二、系統錄屏三、啟動教程四、功能截圖五、文案資料5.1 選題背景5.2 國內外研究現狀 六、核心代碼6.1 查詢數據6.2 新…

如何用 LUKS 和 cryptsetup 為 Linux 配置加密

在信息安全愈發重要的今天&#xff0c;為 Linux 系統盤配置全盤加密已經成為很多企業和個人的選擇。LUKS&#xff08;Linux Unified Key Setup&#xff09;配合工具 cryptsetup 可以在不犧牲性能的前提下實現高強度加密。本文將通過一個故事化的場景&#xff0c;介紹整個配置過…

VIVADO技巧_BUFGMUX時序優化

1.版本說明日期作者版本說明2025xxxx風釋雪初始版本 2.概述 基于VIVADO時序約束&#xff0c;BUFGMUX多路時鐘選擇原語的設計3.原語介紹 7系列FPGA/UltraSCale/UltraSCaleBUFGMUX_CTRL BUFGMUX_CTRL_inst (.O(O), // 1-bit output: Clock output.I0(I0), // 1-bit input: Cloc…