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