SpringCloud?Sentinel服務(wù)保護(hù)詳解(請(qǐng)求限流、線程隔離、服務(wù)熔斷)
開發(fā)環(huán)境
環(huán)境:Java 11、MySQL 8.0、OpenFeign、sentinel-dashboard 1.8.6
為什么要保護(hù)
微服務(wù)在遠(yuǎn)程調(diào)用時(shí),可能存在以下問題:
1. 業(yè)務(wù)健壯性:
如,購物車服務(wù)、商品服務(wù)之間互相調(diào)用,當(dāng)一方掛掉,需要做兜底處理從而優(yōu)化用戶體驗(yàn)
假設(shè),查詢購物車接口需要調(diào)用商品服務(wù),商品服務(wù)掛了導(dǎo)致查詢失敗,但從業(yè)務(wù)角度為了提高用戶體驗(yàn),即使查詢失敗,購物車列表也應(yīng)該展示出來(展示空數(shù)據(jù)/緩存數(shù)據(jù))。而不是丟給用戶一堆報(bào)錯(cuò)信息。
2. 級(jí)聯(lián)失?。ㄑ┍绬栴}):
如,高峰期時(shí)查詢接口并發(fā)高,其他接口并發(fā)??;由于高并發(fā)接口占用過多的Tomcat連接,可能導(dǎo)致所有接口都延遲變高、長(zhǎng)時(shí)間阻塞甚至失敗。
以此類推,當(dāng)互相調(diào)用的服務(wù)間出現(xiàn)問題時(shí),可能導(dǎo)致整個(gè)集群都不可用
Sentinel 實(shí)現(xiàn)保護(hù)
提示:這里可以添加要學(xué)的內(nèi)容
例如:
- 搭建 Java 開發(fā)環(huán)境
- 掌握 Java 基本語法
- 掌握條件語句
- 掌握循環(huán)語句
策略1:請(qǐng)求限流
理解:限制/控制接口的請(qǐng)求流量
并發(fā)太高是導(dǎo)致服務(wù)故障的重要原因。
因此通過限制或控制接口的并發(fā)流量,避免服務(wù)因流量激增而出現(xiàn)故障。
策略2:線程隔離
理解:提前分配好資源(線程)給業(yè)務(wù)接口
當(dāng)一個(gè)業(yè)務(wù)接口響應(yīng)時(shí)間長(zhǎng),而且并發(fā)高時(shí),就可能耗盡服務(wù)器的線程資源,導(dǎo)致服務(wù)內(nèi)的其它接口受到影響。
因此為了降低/減小這種影響,使用線程隔離,其思想?yún)⒖寂摫谀P?/p>
如,查詢接口訪問頻繁,會(huì)無休止地占用更多的線程資源,而導(dǎo)致其他業(yè)務(wù)的線程資源緊張或無法分配。
線程隔離:鎖死查詢接口20線程,其他業(yè)務(wù)10線程,就算查詢接口并發(fā)再高,只給20線程資源去調(diào)用,確保了其他業(yè)務(wù)不被影響。
策略3:服務(wù)熔斷
理解:對(duì)故障/速度慢的接口進(jìn)行暫時(shí)切斷,并提供一個(gè)友好提示以優(yōu)化用戶體驗(yàn)
服務(wù)熔斷主要有兩點(diǎn):
- 編寫服務(wù)降級(jí)邏輯:調(diào)用失敗后的處理邏輯,可拋出異常/友好提示/默認(rèn)數(shù)據(jù)/緩存數(shù)據(jù)。
- 異常統(tǒng)計(jì)和熔斷:統(tǒng)計(jì)異常比例,當(dāng)比例過高表明該接口會(huì)影響到其它服務(wù),應(yīng)該拒絕調(diào)用該接口,而是直接走降級(jí)邏輯。
Sentinel 流量控制
Sentinel 主要有兩部分
- 核心庫(Jar包):直接引入到
pom.xml
就生效,在項(xiàng)目中可以編程式編寫限流、隔離、熔斷等規(guī)則。 - 控制臺(tái)(DashBoard):負(fù)責(zé)管理推送規(guī)則、監(jiān)控、管理機(jī)器信息等。
依賴引入:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2021.0.4.0</version> </dependency>
控制臺(tái)啟動(dòng):
下載:控制臺(tái)jar包
啟動(dòng):java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
配置application.yaml
spring: cloud: sentinel: transport: dashboard: localhost:8090 http-method-specify: true # 開啟請(qǐng)求方式前綴(為了區(qū)分GET/POST/DELETE等請(qǐng)求)
配置策略
細(xì)節(jié)1:需要觸發(fā)一次請(qǐng)求才會(huì)在Sentinel面板看到該接口的簇點(diǎn)
細(xì)節(jié)2:默認(rèn)直接在面板上的配置是臨時(shí)的,重啟服務(wù)后配置就清空了
具體的流控規(guī)則需要根據(jù)業(yè)務(wù)來進(jìn)行設(shè)置
Sentinel 服務(wù)熔斷
問題1:當(dāng)接口觸發(fā)Sentinel配置的流控規(guī)則時(shí),拋出異常,用戶體驗(yàn)不佳
解決方案:降級(jí)處理,展示空數(shù)據(jù)/緩存的舊數(shù)據(jù)
問題2:當(dāng)A接口需要遠(yuǎn)程調(diào)用B,而B延遲較高,拖慢了A的服務(wù),用戶體驗(yàn)差
解決方案:熔斷慢接口,直接停止使用B接口,走降級(jí)邏輯
本次練習(xí)采用的是OpenFeign遠(yuǎn)程調(diào)用,使用遠(yuǎn)程調(diào)用主要有兩種方式
- 方式一:FallbackClass,無法對(duì)遠(yuǎn)程調(diào)用的異常做處理
- 方式二:FallbackFactory,可以對(duì)遠(yuǎn)程調(diào)用的異常做處理,我們一般選擇這種方式。
故使用更為靈活的FallbackFactory
首先配置降級(jí)邏輯:返回空集合
@Slf4j public class ItemClientFallback implements FallbackFactory<ItemClient> { @Override public ItemClient create(Throwable cause) { return new ItemClient() { @Override public List<ItemDTO> queryItemByIds(Collection<Long> ids) { log.error("遠(yuǎn)程調(diào)用ItemClient#queryItemByIds方法出現(xiàn)異常,參數(shù):{}", ids, cause); // 查詢購物車允許失敗,查詢失敗,返回空集合 return CollUtils.emptyList(); } @Override public void deductStock(List<OrderDetailDTO> items) { log.error("扣減商品庫存失敗!",cause); // 庫存扣減業(yè)務(wù)需要觸發(fā)事務(wù)回滾,查詢失敗,拋出異常 throw new BizIllegalException(cause); } }; } }
將降級(jí)處理邏輯注冊(cè)成@Bean
/** * Feign配置類 */ public class DefaultFeignConfig { @Bean public ItemClientFallback itemClientFallback(){ return new ItemClientFallback(); } }
在遠(yuǎn)程調(diào)用的注解處配置:失敗處理邏輯的類
/** * 遠(yuǎn)程調(diào)用商品服務(wù) */ @FeignClient(value = "item-service",fallbackFactory = ItemClientFallback.class) public interface ItemClient { ... }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringAop中AspectJ框架的切入點(diǎn)表達(dá)式
這篇文章主要介紹了SpringAop中AspectJ框架的切入點(diǎn)表達(dá)式,AspectJ是一個(gè)基于Java語言的AOP框架,Spring2.0以后新增了對(duì)AspectJ切點(diǎn)表達(dá)式支持,@AspectJ 是AspectJ1.5新增功能,通過JDK5注解技術(shù),允許直接在Bean類中定義切面,需要的朋友可以參考下2023-08-08深入理解SpringMVC中央調(diào)度器DispatcherServlet
這篇文章主要介紹了SpringMVC核心之中央調(diào)度器DispatcherServlet的相關(guān)知識(shí),包括SpringMVC請(qǐng)求處理過程及SrpingMVC容器和spring?IOC容器關(guān)系,需要的朋友可以參考下2022-05-05Spring AI與DeepSeek實(shí)戰(zhàn)一之快速打造智能對(duì)話應(yīng)用
本文詳細(xì)介紹了如何通過SpringAI框架集成DeepSeek大模型,實(shí)現(xiàn)普通對(duì)話和流式對(duì)話功能,步驟包括申請(qǐng)API-KEY、項(xiàng)目搭建、配置API-KEY、創(chuàng)建ChatClient對(duì)象、創(chuàng)建對(duì)話接口、切換模型、使用prompt模板、流式對(duì)話等,感興趣的朋友一起看看吧2025-03-03Java中的信息摘要算法MessageDigest類用法詳解
這篇文章主要介紹了Java中的信息摘要算法MessageDigest類用法詳解,java.security.MessageDigest類為應(yīng)用程序提供信息摘要算法的功能,如MD5或SHA-1或SHA-256算法,信息摘要是安全的單向哈希函數(shù),它接收任意大小的數(shù)據(jù),并輸出固定長(zhǎng)度的哈希值,需要的朋友可以參考下2024-01-01關(guān)于shiro中部分SpringCache失效問題的解決方法
這篇文章主要給大家介紹了關(guān)于shiro中部分SpringCache失效問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07FastJson對(duì)于JSON格式字符串、JSON對(duì)象及JavaBean之間的相互轉(zhuǎn)換操作
這篇文章主要介紹了FastJson對(duì)于JSON格式字符串、JSON對(duì)象及JavaBean之間的相互轉(zhuǎn)換,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11Java的線程池ThreadPoolExecutor及多種線程池實(shí)現(xiàn)詳解
這篇文章主要介紹了Java的線程池ThreadPoolExecutor及多種線程池實(shí)現(xiàn)詳解,ThreadPoolExecutor 使用 int 的高 3 位來表示線程池狀態(tài),低 29 位表示線程數(shù)量,之所以將信息存儲(chǔ)在一個(gè)變量中,是為了保證原子性,需要的朋友可以參考下2024-01-01