SpringCloud-Alibaba-Sentinel服務(wù)降級(jí),熱點(diǎn)限流,服務(wù)熔斷
前言:
除了流量控制以外,對(duì)調(diào)用鏈路中不穩(wěn)定的資源進(jìn)行熔斷降級(jí)也是保障高可用的重要措施之一。一個(gè)服務(wù)常常會(huì)調(diào)用別的模塊,可能是另外的一個(gè)遠(yuǎn)程服務(wù)、數(shù)據(jù)庫(kù),或者第三方 API 等。例如,支付的時(shí)候,可能需要遠(yuǎn)程調(diào)用銀聯(lián)提供的 API;查詢(xún)某個(gè)商品的價(jià)格,可能需要進(jìn)行數(shù)據(jù)庫(kù)查詢(xún)。然而,這個(gè)被依賴(lài)服務(wù)的穩(wěn)定性是不能保證的。如果依賴(lài)的服務(wù)出現(xiàn)了不穩(wěn)定的情況,請(qǐng)求的響應(yīng)時(shí)間變長(zhǎng),那么調(diào)用服務(wù)的方法的響應(yīng)時(shí)間也會(huì)變長(zhǎng),線程會(huì)產(chǎn)生堆積,最終可能耗盡業(yè)務(wù)自身的線程池,服務(wù)本身也變得不可用

熔斷策略
Sentinel 提供以下幾種熔斷策略:
慢調(diào)用比例 (SLOW_REQUEST_RATIO):選擇以慢調(diào)用比例作為閾值,需要設(shè)置允許的慢調(diào)用 RT(即最大的響應(yīng)時(shí)間),請(qǐng)求的響應(yīng)時(shí)間大于該值則統(tǒng)計(jì)為慢調(diào)用。當(dāng)單位統(tǒng)計(jì)時(shí)長(zhǎng)(statIntervalMs)內(nèi)請(qǐng)求數(shù)目大于設(shè)置的最小請(qǐng)求數(shù)目,并且慢調(diào)用的比例大于閾值,則接下來(lái)的熔斷時(shí)長(zhǎng)內(nèi)請(qǐng)求會(huì)自動(dòng)被熔斷。經(jīng)過(guò)熔斷時(shí)長(zhǎng)后熔斷器會(huì)進(jìn)入探測(cè)恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來(lái)的一個(gè)請(qǐng)求響應(yīng)時(shí)間小于設(shè)置的慢調(diào)用 RT 則結(jié)束熔斷,若大于設(shè)置的慢調(diào)用 RT 則會(huì)再次被熔斷。
異常比例 (ERROR_RATIO):當(dāng)單位統(tǒng)計(jì)時(shí)長(zhǎng)(statIntervalMs)內(nèi)請(qǐng)求數(shù)目大于設(shè)置的最小請(qǐng)求數(shù)目,并且異常的比例大于閾值,則接下來(lái)的熔斷時(shí)長(zhǎng)內(nèi)請(qǐng)求會(huì)自動(dòng)被熔斷。經(jīng)過(guò)熔斷時(shí)長(zhǎng)后熔斷器會(huì)進(jìn)入探測(cè)恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來(lái)的一個(gè)請(qǐng)求成功完成(沒(méi)有錯(cuò)誤)則結(jié)束熔斷,否則會(huì)再次被熔斷。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%。
異常數(shù) (ERROR_COUNT):當(dāng)單位統(tǒng)計(jì)時(shí)長(zhǎng)內(nèi)的異常數(shù)目超過(guò)閾值之后會(huì)自動(dòng)進(jìn)行熔斷。經(jīng)過(guò)熔斷時(shí)長(zhǎng)后熔斷器會(huì)進(jìn)入探測(cè)恢復(fù)狀態(tài)(HALF-OPEN 狀態(tài)),若接下來(lái)的一個(gè)請(qǐng)求成功完成(沒(méi)有錯(cuò)誤)則結(jié)束熔斷,否則會(huì)再次被熔斷、

慢調(diào)用比例:
最大 RT:200意思是 在200毫秒處理完這個(gè)請(qǐng)求
比例閥值:1 意思是是 在200毫秒處理一個(gè)請(qǐng)求 你設(shè)置幾就就200毫秒處理幾個(gè)
熔斷時(shí)長(zhǎng):1意思是一秒內(nèi)不可用
最小請(qǐng)求數(shù):5 意思是 一秒5次請(qǐng)求


異常比例:
比例閥值:官網(wǎng):(異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%)0.3意思錯(cuò)誤的達(dá)到了百分之30的時(shí)候 觸發(fā)熔斷
熔斷時(shí)間:1的意思是一秒之間不可用
最小請(qǐng)求數(shù):5一秒5個(gè)

異常數(shù)
異常數(shù):3意思是超過(guò)3個(gè)異常,就是第4次進(jìn)入熔斷服務(wù)降級(jí),當(dāng)?shù)谖宕握?qǐng)求是對(duì)的就會(huì)恢復(fù)
熔斷時(shí)長(zhǎng):1秒

熱點(diǎn)參數(shù)限流
何為熱點(diǎn)?熱點(diǎn)即經(jīng)常訪問(wèn)的數(shù)據(jù)。很多時(shí)候我們希望統(tǒng)計(jì)某個(gè)熱點(diǎn)數(shù)據(jù)中訪問(wèn)頻次最高的 Top K 數(shù)據(jù),并對(duì)其訪問(wèn)進(jìn)行限制。比如:
商品 ID 為參數(shù),統(tǒng)計(jì)一段時(shí)間內(nèi)最常購(gòu)買(mǎi)的商品 ID 并進(jìn)行限制
用戶(hù) ID 為參數(shù),針對(duì)一段時(shí)間內(nèi)頻繁訪問(wèn)的用戶(hù) ID 進(jìn)行限制
熱點(diǎn)參數(shù)限流會(huì)統(tǒng)計(jì)傳入?yún)?shù)中的熱點(diǎn)參數(shù),并根據(jù)配置的限流閾值與模式,對(duì)包含熱點(diǎn)參數(shù)的資源調(diào)用進(jìn)行限流。熱點(diǎn)參數(shù)限流可以看做是一種特殊的流量控制,僅對(duì)包含熱點(diǎn)參數(shù)的資源調(diào)用生效。

示例:
這里有兩個(gè) 參數(shù)一個(gè)是A 一個(gè)是B熱點(diǎn)限流是根據(jù)設(shè)置參數(shù)的下標(biāo)設(shè)置的,下表是從0開(kāi)始的,
@SentinelResource注解設(shè)置要限流的id, blockHandler設(shè)置返回可預(yù)知的響應(yīng)體
@GetMapping(value = "select/test")
@SentinelResource(value = "test",blockHandler = "teat1")
public String test(@RequestParam(value = "a",required = false) Integer a,@RequestParam(value = "b",required = false) Integer b){
return "我是:Sentinel";
}
設(shè)置的可預(yù)知的響應(yīng)體這個(gè)的BlockException是必須的參數(shù)
public String teat1(@RequestParam(value = "a",required = false) Integer a,@RequestParam(value = "b",required = false)Integer b, BlockException e){
return "沒(méi)錯(cuò)我就是我了";
}
配置
test是@SentinelResource(value = "test",blockHandler = "teat1")
參數(shù)索引:0就是0下標(biāo)
單機(jī)閥值:1處理的個(gè)數(shù)
統(tǒng)計(jì)窗口時(shí)長(zhǎng) 1是一秒處理完成

高級(jí)選項(xiàng)

參數(shù)類(lèi)型:選擇參數(shù)的數(shù)據(jù)類(lèi)型
參數(shù)值:1就參數(shù)如果等于1就限流
限流閥: 3就是3次

這些可以自己測(cè)試

服務(wù)熔斷
Sentinel 提供了 @SentinelResource 注解用于定義資源,并提供了 AspectJ 的擴(kuò)展用于自動(dòng)定義資源、處理 BlockException 等。
@SentinelResource 注解
@SentinelResource 用于定義資源,并提供可選的異常處理和 fallback 配置項(xiàng)。 @SentinelResource 注解包含以下屬性:
value:資源名稱(chēng),必需項(xiàng)(不能為空)
entryType:entry 類(lèi)型,可選項(xiàng)(默認(rèn)為 EntryType.OUT)
blockHandler / blockHandlerClass: blockHandler 對(duì)應(yīng)處理 BlockException 的函數(shù)名稱(chēng),可選項(xiàng)。blockHandler 函數(shù)訪問(wèn)范圍需要是 public,返回類(lèi)型需要與原方法相匹配,參數(shù)類(lèi)型需要和原方法相匹配并且最后加一個(gè)額外的參數(shù),類(lèi)型為 BlockException。blockHandler 函數(shù)默認(rèn)需要和原方法在同一個(gè)類(lèi)中。若希望使用其他類(lèi)的函數(shù),則可以指定 blockHandlerClass 為對(duì)應(yīng)的類(lèi)的 Class 對(duì)象,注意對(duì)應(yīng)的函數(shù)必需為 static 函數(shù),否則無(wú)法解析。
fallback / fallbackClass:fallback 函數(shù)名稱(chēng),可選項(xiàng),用于在拋出異常的時(shí)候提供 fallback 處理邏輯。fallback 函數(shù)可以針對(duì)所有類(lèi)型的異常(除了 exceptionsToIgnore 里面排除掉的異常類(lèi)型)進(jìn)行處理。fallback 函數(shù)簽名和位置要求:
返回值類(lèi)型必須與原函數(shù)返回值類(lèi)型一致;
方法參數(shù)列表需要和原函數(shù)一致,或者可以額外多一個(gè) Throwable 類(lèi)型的參數(shù)用于接收對(duì)應(yīng)的異常。
fallback 函數(shù)默認(rèn)需要和原方法在同一個(gè)類(lèi)中。若希望使用其他類(lèi)的函數(shù),則可以指定 fallbackClass 為對(duì)應(yīng)的類(lèi)的 Class 對(duì)象,注意對(duì)應(yīng)的函數(shù)必需為 static 函數(shù),否則無(wú)法解析。
defaultFallback(since 1.6.0):默認(rèn)的 fallback 函數(shù)名稱(chēng),可選項(xiàng),通常用于通用的 fallback 邏輯(即可以用于很多服務(wù)或方法)。默認(rèn) fallback 函數(shù)可以針對(duì)所有類(lèi)型的異常(除了 exceptionsToIgnore 里面排除掉的異常類(lèi)型)進(jìn)行處理。若同時(shí)配置了 fallback 和 defaultFallback,則只有 fallback 會(huì)生效。defaultFallback 函數(shù)簽名要求:
返回值類(lèi)型必須與原函數(shù)返回值類(lèi)型一致;
方法參數(shù)列表需要為空,或者可以額外多一個(gè) Throwable 類(lèi)型的參數(shù)用于接收對(duì)應(yīng)的異常。
defaultFallback 函數(shù)默認(rèn)需要和原方法在同一個(gè)類(lèi)中。若希望使用其他類(lèi)的函數(shù),則可以指定 fallbackClass 為對(duì)應(yīng)的類(lèi)的 Class 對(duì)象,注意對(duì)應(yīng)的函數(shù)必需為 static 函數(shù),否則無(wú)法解析。
exceptionsToIgnore(since 1.6.0):用于指定哪些異常被排除掉,不會(huì)計(jì)入異常統(tǒng)計(jì)中,也不會(huì)進(jìn)入 fallback 邏輯中,而是會(huì)原樣拋出。
1.8.0 版本開(kāi)始,defaultFallback 支持在類(lèi)級(jí)別進(jìn)行配置。
注:1.6.0 之前的版本 fallback 函數(shù)只針對(duì)降級(jí)異常(DegradeException)進(jìn)行處理,不能針對(duì)業(yè)務(wù)異常進(jìn)行處理。
特別地,若 blockHandler 和 fallback 都進(jìn)行了配置,則被限流降級(jí)而拋出 BlockException 時(shí)只會(huì)進(jìn)入 blockHandler 處理邏輯。若未配置 blockHandler、fallback 和 defaultFallback,則被限流降級(jí)時(shí)會(huì)將 BlockException 直接拋出(若方法本身未定義 throws BlockException 則會(huì)被 JVM 包裝一層 UndeclaredThrowableException)。
示例:
1,fallback處理java異常
@SentinelResource(value = "select",fallback = "ErrorFallback")
代碼
@GetMapping(value = "select/{id}")
@SentinelResource(value = "select",fallback = "ErrorFallback")
public CommonResult getid(@PathVariable Long id){
if(id>3) {
throw new NullPointerException(id+"沒(méi)有記錄");
}else {
return restTemplate.getForObject(URL + "/select/" + id, CommonResult.class);
}
}
fallback 處理方法
public CommonResult ErrorFallback(@PathVariable Long id,Throwable e){
return new CommonResult<>(500,"不好意,沒(méi)有此記錄");
}
處理結(jié)果

blockHandler 處理sentinel配置異常 java的異常無(wú)法處理
@SentinelResource(value = "select",blockHandler = "ErrorFallback")
public CommonResult ErrorFallback(@PathVariable Long id, BlockException e){
return new CommonResult<>(500,"不好意,沒(méi)有此記錄"+e.getMessage());
}
測(cè)試
這設(shè)置的是異常比例 異常達(dá)到百分之30進(jìn)行熔斷



兩個(gè)注解同時(shí)用
@SentinelResource(value = "select",blockHandler = "ErrorFallback",fallback = "ErrorFallback1")
public CommonResult ErrorFallback1(@PathVariable Long id, Throwable e){
return new CommonResult<>(500,"fallback:不好意,沒(méi)有此記錄"+e.getMessage());
}
public CommonResult ErrorFallback(@PathVariable Long id, BlockException e){
return new CommonResult<>(500,"blockHandler:不好意,沒(méi)有此記錄"+e.getMessage());
}


但是 要是blockHandler 和fallback 同時(shí)配置則被限流降級(jí)拋出異常BlockException 處理
exceptionsToIgnore
@SentinelResource(value = "select",blockHandler = "ErrorFallback",fallback = "ErrorFallback1"
,exceptionsToIgnore = {IllegalAccessException.class})
blockHandlerClass=定義返回統(tǒng)一返回方法.class
業(yè)務(wù)
@GetMapping(value = "select/test")
@SentinelResource(value = "test",blockHandlerClass= MySentinel.class,blockHandler = "a")
public String test(@RequestParam(value = "a",required = false) Integer a,@RequestParam(value = "b",required = false) Integer b){
return "我是:Sentinel";
}
熔斷降級(jí)
package com.tang.cloud.mysentinel;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import jdk.nashorn.internal.ir.Block;
import org.bouncycastle.crypto.engines.BlowfishEngine;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 統(tǒng)一返回降級(jí)處理
*/
public class MySentinel {
//返回的的類(lèi)型和調(diào)用的方法的類(lèi)型一致,參數(shù)的類(lèi)型和個(gè)數(shù)相同
public static String a(@RequestParam(value = "a",required = false) Integer a, @RequestParam(value = "b",required = false) Integer b, BlockException excep){
return "我在在另一個(gè)類(lèi)中定義的方法";
}
}
到此這篇關(guān)于SpringCloud-Alibaba-Sentinel服務(wù)降級(jí)熱點(diǎn)限流服務(wù)熔斷的文章就介紹到這了,更多相關(guān)SpringCloud-Alibaba-Sentinel-服務(wù)降級(jí)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java二維數(shù)組實(shí)現(xiàn)數(shù)字拼圖效果
這篇文章主要為大家詳細(xì)介紹了Java二維數(shù)組實(shí)現(xiàn)數(shù)字拼圖效果,控制臺(tái)可以對(duì)空格進(jìn)行移動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
Springboot微服務(wù)打包Docker鏡像流程解析
這篇文章主要介紹了Springboot微服務(wù)打包Docker鏡像流程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
簡(jiǎn)易版SpringBoot自定義模擬實(shí)現(xiàn)
SpringBoot作為目前最流行的框架之一,極大地提高了開(kāi)發(fā)效率和降低了學(xué)習(xí)成本,使得開(kāi)發(fā)人員能夠更專(zhuān)注于業(yè)務(wù)邏輯的實(shí)現(xiàn),而無(wú)需過(guò)多關(guān)注底層框架的配置和集成,本文模擬實(shí)現(xiàn)簡(jiǎn)易版SpringBoot2024-01-01
Java JTable 實(shí)現(xiàn)日歷的示例
這篇文章主要介紹了Java JTable 實(shí)現(xiàn)日歷的示例,幫助大家更好的理解和學(xué)習(xí)Java jtable的使用方法,感興趣的朋友可以了解下2020-10-10
解決@PathVariable對(duì)于特殊字符截?cái)嗟膯?wèn)題
這篇文章主要介紹了解決@PathVariable對(duì)于特殊字符截?cái)嗟膯?wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
在SpringBoot中,如何使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用方法總結(jié)
我們?cè)谶M(jìn)行網(wǎng)絡(luò)連接的時(shí)候,建立套接字連接是一個(gè)非常消耗性能的事情,特別是在分布式的情況下,用線程池去保持多個(gè)客戶(hù)端連接,是一種非常消耗線程的行為.那么我們?cè)撏ㄟ^(guò)什么技術(shù)去解決上述的問(wèn)題呢,那么就不得不提一個(gè)網(wǎng)絡(luò)連接的利器——Netty,需要的朋友可以參考下2021-06-06
Java?Elastic-Job分布式定時(shí)任務(wù)使用方法介紹
xxl-job?通過(guò)一個(gè)中心式的調(diào)度平臺(tái),調(diào)度多個(gè)執(zhí)行器執(zhí)行任務(wù),調(diào)度中心通過(guò)?DB?鎖保證集群分布式調(diào)度的一致性,這樣擴(kuò)展執(zhí)行器會(huì)增大?DB?的壓力,然而大部分公司的任務(wù)數(shù),執(zhí)行器并不多;xxl-job?提供了非常好用的監(jiān)控頁(yè)面甚至還有任務(wù)失敗的郵件告警功能2023-01-01
Java實(shí)現(xiàn)終止線程池中正在運(yùn)行的定時(shí)任務(wù)
本篇文章給大家分享了JAVA中實(shí)現(xiàn)終止線程池中正在運(yùn)行的定時(shí)任務(wù)的具體步驟和方法,有需要的朋友跟著學(xué)習(xí)下。2018-05-05

