Spring Cloud系列—Alibaba Sentinel熔斷降級

上篇文章:

Spring Cloud系列— Alibaba Sentinel限流https://blog.csdn.net/sniper_fandc/article/details/149944260?fromshare=blogdetail&sharetype=blogdetail&sharerId=149944260&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link

目錄

1 熔斷策略

1.1 狀態機

1.2 慢調用比例(SLOW_REQUEST_RATIO)

1.3 異常比例(ERROR_RATIO)

1.4 異常數(ERROR_COUNT)

2 降級

2.1 捕獲異常

2.2 FallbackFactory


1 熔斷策略

????????當微服務系統中存在某個服務或接口故障,由于調用鏈路比較復雜,某個接口的故障可能就會導致整個系統不可用。因此需要對故障的接口或服務進行熔斷降級,熔斷降級主要是對弱依賴服務(不是系統運行的必須服務組件),常見三種策略:

1.1 狀態機

????????熔斷是由斷路機(熔斷器)統計服務調用的慢調用比例、異常比例和異常數,如果超過閾值則進行熔斷,攔截請求該服務的請求;否則放行請求該服務的請求。斷路機是基于狀態機來完成工作的:

????????狀態機有三種狀態:OPEN、HALF_OPEN和CLOSED。

????????CLOSED:所有請求都會通過斷路機,通過的過程中統計慢調用比例、異常比例和異常數,如果失敗率高于閾值就會轉化為OPEN狀態。

????????OPEN:所有請求都會被斷路機攔截,即服務被熔斷。每隔一段時間轉化為HALF_OPEN狀態,并將一定的請求放入斷路機。

????????HALF_OPEN:OPEN狀態每隔一段時間轉化為HALF_OPEN狀態,并根據放入的請求統計慢調用比例、異常比例和異常數,如果失敗率高于閾值,則此時服務還得繼續熔斷,因此再次轉化為OPEN狀態;如果失敗率低于閾值,則此時服務被視為可以正常訪問,不需要進行熔斷,因此轉化為CLOSED狀態。

1.2 慢調用比例(SLOW_REQUEST_RATIO)

????????在統計時長內,請求數超過最小請求數,且慢調用(請求響應時間超過最大RT(最大響應時間))比例超過比例閾值,就進行熔斷,暫停該資源一定時間(熔斷時長)的訪問。

????????假設order-service服務調用product-service服務的接口,如果product-service服務的接口出現響應速度慢的情況,則會被認為是慢調用請求:

????@RequestMapping("/{productId}")public ProductInfo getProductById(@PathVariable("productId") Integer productId){try {long millis = new Random().nextInt(20)+50;Thread.sleep(millis);//模擬慢調用System.out.println("收到請求,Id:"+productId);return productService.selectProductById(productId);} catch (InterruptedException e) {throw new RuntimeException(e);}}

????????將調用方的調用方法定義為資源,便于設置熔斷規則:

????@SentinelResource("selectOrderById")public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);//OpenFeign遠程調用方式ProductInfo productInfo = productInterface.getProductById(orderInfo.getProductId());orderInfo.setProductInfo(productInfo);return orderInfo;}

????????針對資源設置熔斷規則,10s內如果請求數超過5次,并且慢調用(響應時間超過50ms)比例超過0.5,則熔斷5s:

????????當重啟服務后,快速手動多次發送請求,如果發送請求超過5次以上,就會出現熔斷現象:

1.3 異常比例(ERROR_RATIO)

????????在統計時長內,請求數超過最小請求數,且異常比例超過比例閾值,就進行熔斷,暫停該資源一定時間(熔斷時長)的訪問。

????????首先在被調用接口中分別設置慢調用和異常兩種情況,由于(這里用到了服務降級,會在下面進行闡述)服務降級會針對異常也生效,因此想要觀察熔斷,就需要先調用慢調用接口(沒有設置慢調用的熔斷策略,因此不會熔斷)會正常通行,再多次調用異常接口觸發熔斷,最后再調用慢調用接口也會被攔截:

????@RequestMapping("/{productId}")public ProductInfo getProductById(@PathVariable("productId") Integer productId) {if (productId == 1001) {//模擬慢響應try {Thread.sleep(60);} catch (InterruptedException e) {throw new RuntimeException(e);}} else if (productId == 1002) {// 模擬異常throw new RuntimeException("發生異常");}return productService.selectProductById(productId);}

????????設置熔斷策略為異常比例,10s請求數大于5次,異常比例超過50%就觸發5s熔斷:

????????調用order/1接口,最終會遠程調用product/1001接口,不會觸發熔斷:

????????調用order/2接口,最終會遠程調用product/1002接口,多次調用會觸發熔斷(異常比例超過50%):

????????在觸發熔斷后,調用order/1接口,可以發現productInfo為NULL,說明觸發熔斷,并且服務降級:

1.4 異常數(ERROR_COUNT)

????????在統計時長內,請求數超過最小請求數,且發生異常的數量超過設置的異常數,就進行熔斷,暫停該資源一定時間(熔斷時長)的訪問。

????????異常數與異常比例類似,只不過熔斷判斷標準變為超過數字而不是比例。

2 降級

????????上述慢調用熔斷時,用戶會直接看到500內部異常這個響應,這對用戶體驗并不好。應該針對失敗返回用戶友好性的提示或默認結果,這就是降級。

????????實現服務降級有兩種方式:

????????1.捕獲異常,根據異常邏輯來進行降級。適用于通用場景。

????????2.FallbackFactory,適合遠程調用場景。

2.1 捕獲異常

????????由于訪問的是/order/{orderId}接口,因此可以在調用時發生異常后返回一個NULL對象:

????@SentinelResource("order-param")@RequestMapping("/{orderId}")public OrderInfo getOrderById(@PathVariable("orderId") Integer orderId) {try {OrderInfo orderInfo = orderService.selectOrderById(orderId);return orderInfo;}catch (UndeclaredThrowableException e){System.out.println("獲取訂單發生異常,exception:"+e);;return new OrderInfo();}}

????????此時在發生熔斷,就不會直接在頁面顯示500內部異常,而是一個NULL對象:

2.2 FallbackFactory

????????FallbackFactory是微服務架構中用于服務降級的接口,可以根據遠程服務調用失敗或異常信息,提供一個降級處理實例,該實例來代替原服務被調用。

????????首先需要創建這個降級處理實例,該實例實現FallbackFactory并接受ProductInterface類型的泛型參數:

@Slf4jpublic class ProductFallbackFactory implements FallbackFactory<ProductInterface> {@Overridepublic ProductInterface create(Throwable cause) {return new ProductInterface() {//返回服務降級實例@Overridepublic ProductInfo getProductById(Integer productId) {log.error("查詢商品信息異常");return new ProductInfo();}@Overridepublic String param1(Integer productId){return "發生錯誤";}@Overridepublic String param2(Integer productId,String name){return "發生錯誤";}@Overridepublic String object(ProductInfo productInfo){return "發生錯誤";}@Overridepublic String json(ProductInfo productInfo){return "發生錯誤";}};}}

????????ProductInterface類型是OpenFeign遠程調用的客戶端(抽取),需要注意設置fallbackFactory來和服務降級實例關聯:

@FeignClient(value = "product-service",path = "/product", fallbackFactory = ProductFallbackFactory.class)public interface ProductInterface {@RequestMapping("/{productId}")ProductInfo getProductById(@PathVariable("productId") Integer productId);@RequestMapping("/param1")String param1(@RequestParam("productId") Integer productId);@RequestMapping("/param2")String param2(@RequestParam("productId")Integer productId,@RequestParam("name")String name);@RequestMapping("/object")String object(@SpringQueryMap ProductInfo productInfo);@RequestMapping("/json")String json(@RequestBody ProductInfo productInfo);}

????????然后還需要定義ProductFallbackFactory的Bean,由于該DefaultFeignConfiguration需要多個遠程調用的接口使用,因此不添加五大注解交給Spring來管理,而是由調用方自行掃描注冊該Bean:

//創建ProductFallbackFactory的Beanpublic class DefaultFeignConfiguration {@Beanpublic ProductFallbackFactory productFallbackFactory() {return new ProductFallbackFactory();}}

????????調用方的啟動類上需要配置OpenFeign客戶端和FallbackFactory管理的服務降級實例的路徑:

@EnableFeignClients(basePackages = {"com.demo.product.api2"},defaultConfiguration = DefaultFeignConfiguration.class)

????????最后在配置文件中開啟OpenFeign的Sentinel的功能:

feign:sentinel:enabled: true # 開啟feign對sentinel的支持

????????重啟服務,觀察服務降級:

????????可以發現,開啟OpenFeign的Sentinel功能后,遠程調用的接口也出現在簇點鏈路中,針對遠程調用設置熔斷降級:

????????此時在多次慢調用出發熔斷后,不再是直接的500內部異常,而是遠程調用的服務降級。并且該服務降級返回了NULL的productInfo對象(服務降級實例),并不是像異常處理那樣處理粒度很粗。

????????注意:FallbackFactory不僅對熔斷生效對限流也生效,即如果觸發限流,頁面不再顯示Blocked by Sentinel,而是返回服務降級實例。并且,服務降級還會對異常生效,即只要程序發生異常,就會走服務降級。因此發生服務降級現象,不一定是因為熔斷,也可能是因為限流或異常。

下篇文章:

Spring Cloud系列—Alibaba Sentinel授權與規則管理及推送https://blog.csdn.net/sniper_fandc/article/details/149945898?fromshare=blogdetail&sharetype=blogdetail&sharerId=149945898&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link

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

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

相關文章

Spring Boot 使用 @NotBlank + @Validated 優雅校驗參數

在日常開發中&#xff0c;我們常用 if (isBlank(...)) 來判斷參數是否為空&#xff0c;但這種方式不僅繁瑣&#xff0c;而且容易遺漏。 Spring 生態中推薦使用 JSR-303 校驗注解&#xff08;NotBlank、NotNull 等&#xff09;配合 Validated 實現自動校驗&#xff0c;大幅減少手…

網絡安全(Java語言)簡單腳本匯總 (一)

文章目錄敏感信息探測腳本源代碼思路URL批量存活探測器源代碼思路端口掃描器源代碼思路 敏感信息探測腳本 源代碼/*** description 該腳本通過分析HTTP響應頭&#xff0c;來檢測可能暴露服務器信息的安全隱患*/import java.io.IOException; import java.net.HttpURLConnection;…

buuctf_NSBlogin_http_upload(極客2019+ACTF2020新生賽)

今天做三1個web 題目&#xff1a;NSB_login用戶名有admin&#xff0c;看源碼&#xff1a;I like rockyou&#xff01;今天學習到&#xff0c;kali里面有密碼爆破的文件叫rockyou.txt&#xff08;/usr/share/wordlists/&#xff09;&#xff08;沒kali也可以去https://gitcode.c…

IDEA如何引用brew安裝的openjdk

因為 brew 安裝的 openjdk@21 目錄結構和 IDEA 期望的 JDK 目錄不一樣。所以默認brew安裝的jdk,在IDEA中是無法識別到的。 一、創建軟連接 sudo mkdir -p /Library/Java/JavaVirtualMachines sudo ln -sfn /usr/local/opt/openjdk@21/libexec/openjdk.jdk /Library/Java/Java…

【Unity3D】Spine黑線(預乘問題)、貼圖邊緣裁剪問題

一、黑線問題 Spine正確的導出和Unity導入設置&#xff08;解決黑邊/彩條帶問題&#xff09;_spine導出的圖片有黑邊-CSDN博客 采用&#xff08;已解決問題&#xff09; Texture 打包器啟用 Premultiply alpha ,禁用Bleed Unity Texture 設置中禁用 sRGB (Color Texture) 和…

嵌入式系統學習Day18(文件編程-系統調用文件IO)

- open#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); 功能:打開文件 參數:pathname --- 文件名 flags 必選:O_RDONLYO_WRONLY…

Vue淺學

概述在最近的學習任務中了解了 Vue&#xff0c;并對其產生了濃厚的興趣&#xff0c;現在分享一下我的學習所得關鍵字其一statestate 是 Vuex 存儲中的“狀態對象”&#xff0c;用于存儲整個應用的共享數據&#xff08;如用戶信息、令牌、權限等&#xff09;&#xff0c;比如&am…

機器翻譯:Hugging Face庫詳解

文章目錄一、Hugging Face概述1.1 Hugging Face介紹1.2 核心理念&#xff1a;模型即服務&#xff0c;但以開源形式二、核心架構2.1 Transformers庫&#xff1a;模型交互的統一接口2.2 Datasets庫&#xff1a;高效的數據處理引擎2.3 Tokenizers庫&#xff1a;文本與模型的“翻譯…

服務器安裝gielab社區版

第一步&#xff1a;安裝Gitlab 1,使用的是CentOs鏡像(服務器最低配置為4核8g內存才行要不然帶不動) 登錄目標實例。 2,執行如下命令&#xff0c;安裝所需依賴。 1 sudo yum install -y curl policycoreutils-python openssh-server 3,執行如下命令&#xff0c;啟動SSH服務…

C#報錯:System.NullReferenceException:“未將對象引用設置到對象的實例。”

C#使用自定義的類創建數組時&#xff0c;使用時報錯&#xff0c;報錯內容如下圖&#xff1a;原因&#xff1a;C#中的數組是引用類型。當聲明自定義類數組時&#xff0c;數組本身會被創建&#xff0c;但其元素&#xff08;即自定義類的實例&#xff09;默認未被實例化&#xff0…

Maven 的 module 管理

一、Maven 的 module 管理 1. 什么是 Maven module&#xff1f; Maven module&#xff08;模塊&#xff09;&#xff0c;是 Maven 多模塊項目結構&#xff08;multi-module project&#xff09;中的核心概念。它允許你將一個大型項目拆分為若干獨立的小項目&#xff08;模塊&am…

現在都是APP,小程序搶購,支持瀏覽器不支持 SSE

在 APP 和小程序搶購場景中&#xff0c;通常不原生支持SSE&#xff08;Server-Sent Events&#xff09;&#xff0c;這與瀏覽器對 SSE 的支持情況不同&#xff0c;具體如下&#xff1a;APP&#xff1a;一般情況下&#xff0c;APP 端不支持原生 SSE。若使用 UniApp 開發&#xf…

Spring Boot 深度解析:從原理到實踐

一、Spring Boot 本質與核心價值 1.1 什么是 Spring Boot&#xff1f; Spring Boot 是 Spring 生態的革命性框架&#xff0c;旨在解決傳統 Spring 開發的復雜性。它通過"約定優于配置"&#xff08;Convention Over Configuration&#xff09;理念&#xff0c;提供開箱…

WebSocket-java篇

問題引入消息推送的方式我們要實現&#xff0c;服務器把消息推送到客戶端&#xff0c;可以輪訓&#xff0c;長輪訓還有sseWebSocket理論WebSocket 的由來與核心價值誕生背景&#xff1a;解決 HTTP 協議在實時通信中的固有缺陷&#xff08;單向請求-響應模式&#xff09;核心驅動…

用Python從零開始實現神經網絡

反向傳播算法用于經典的前饋人工神經網絡。 它仍然是訓練大型深度學習網絡的技術。 在這個教程中&#xff0c;你將學習如何用Python從頭開始實現神經網絡的反向傳播算法。 完成本教程后&#xff0c;您將了解&#xff1a; 如何將輸入前向傳播以計算輸出。如何反向傳播錯誤和…

算法148. 排序鏈表

題目&#xff1a;給你鏈表的頭結點 head &#xff0c;請將其按 升序 排列并返回 排序后的鏈表 。示例 1&#xff1a;輸入&#xff1a;head [4,2,1,3] 輸出&#xff1a;[1,2,3,4] 示例 2&#xff1a;輸入&#xff1a;head [-1,5,3,4,0] 輸出&#xff1a;[-1,0,3,4,5] 示例 3&a…

在騰訊云CodeBuddy上實現一個AI聊天助手

在騰訊云CodeBuddy上實現一個AI聊天助手項目 在當今數字化時代&#xff0c;AI聊天助手已經成為一種非常流行的應用&#xff0c;廣泛應用于客戶服務、智能助手等領域。今天&#xff0c;我們將通過騰訊云CodeBuddy平臺&#xff0c;實現一個基于Spring Boot和OpenAI API的AI聊天助…

JavaScript Array.prototype.flatMap ():數組 “扁平化 + 映射” 的高效組合拳

在 JavaScript 數組處理中&#xff0c;我們經常需要先對每個元素進行轉換&#xff08;映射&#xff09;&#xff0c;再將結果 “鋪平”&#xff08;扁平化&#xff09;。比如將數組中的每個字符串按空格拆分&#xff0c;然后合并成一個新數組。傳統做法是先用map()轉換&#xf…

區塊鏈與元宇宙:數字資產的守護者

1 區塊鏈支撐元宇宙數字資產的底層邏輯1.1 不可篡改性構建信任基石區塊鏈的不可篡改性為元宇宙數字資產提供了堅實的信任基礎。其核心在于分布式賬本技術&#xff0c;當一筆數字資產交易發生時&#xff0c;會被打包成區塊并廣播至網絡中的所有節點。每個節點都會對這筆交易進行…

Linux軟件編程:進程和線程(進程)

進程一、基本概念進程&#xff1a;是程序動態執行過程&#xff0c;包括創建、調度、消亡程序&#xff1a;存放在外存的一段數據的集合二、進程創建&#xff08;一&#xff09;進程空間分布每個進程運行起來后&#xff0c;操作系統開辟0-4G的虛擬空間進程空間&#xff1a;用戶空…