SpringCloud?Sentinel服務保護詳解(請求限流、線程隔離、服務熔斷)
開發(fā)環(huán)境
環(huán)境:Java 11、MySQL 8.0、OpenFeign、sentinel-dashboard 1.8.6
為什么要保護
微服務在遠程調用時,可能存在以下問題:
1. 業(yè)務健壯性:
如,購物車服務、商品服務之間互相調用,當一方掛掉,需要做兜底處理從而優(yōu)化用戶體驗
假設,查詢購物車接口需要調用商品服務,商品服務掛了導致查詢失敗,但從業(yè)務角度為了提高用戶體驗,即使查詢失敗,購物車列表也應該展示出來(展示空數(shù)據(jù)/緩存數(shù)據(jù))。而不是丟給用戶一堆報錯信息。
2. 級聯(lián)失?。ㄑ┍绬栴}):
如,高峰期時查詢接口并發(fā)高,其他接口并發(fā)?。挥捎诟卟l(fā)接口占用過多的Tomcat連接,可能導致所有接口都延遲變高、長時間阻塞甚至失敗。

以此類推,當互相調用的服務間出現(xiàn)問題時,可能導致整個集群都不可用

Sentinel 實現(xiàn)保護
提示:這里可以添加要學的內容
例如:
- 搭建 Java 開發(fā)環(huán)境
- 掌握 Java 基本語法
- 掌握條件語句
- 掌握循環(huán)語句
策略1:請求限流
理解:限制/控制接口的請求流量
并發(fā)太高是導致服務故障的重要原因。
因此通過限制或控制接口的并發(fā)流量,避免服務因流量激增而出現(xiàn)故障。

策略2:線程隔離
理解:提前分配好資源(線程)給業(yè)務接口
當一個業(yè)務接口響應時間長,而且并發(fā)高時,就可能耗盡服務器的線程資源,導致服務內的其它接口受到影響。
因此為了降低/減小這種影響,使用線程隔離,其思想?yún)⒖寂摫谀P?/p>

如,查詢接口訪問頻繁,會無休止地占用更多的線程資源,而導致其他業(yè)務的線程資源緊張或無法分配。
線程隔離:鎖死查詢接口20線程,其他業(yè)務10線程,就算查詢接口并發(fā)再高,只給20線程資源去調用,確保了其他業(yè)務不被影響。

策略3:服務熔斷
理解:對故障/速度慢的接口進行暫時切斷,并提供一個友好提示以優(yōu)化用戶體驗
服務熔斷主要有兩點:
- 編寫服務降級邏輯:調用失敗后的處理邏輯,可拋出異常/友好提示/默認數(shù)據(jù)/緩存數(shù)據(jù)。
- 異常統(tǒng)計和熔斷:統(tǒng)計異常比例,當比例過高表明該接口會影響到其它服務,應該拒絕調用該接口,而是直接走降級邏輯。

Sentinel 流量控制
Sentinel 主要有兩部分
- 核心庫(Jar包):直接引入到
pom.xml就生效,在項目中可以編程式編寫限流、隔離、熔斷等規(guī)則。 - 控制臺(DashBoard):負責管理推送規(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:默認直接在面板上的配置是臨時的,重啟服務后配置就清空了
具體的流控規(guī)則需要根據(jù)業(yè)務來進行設置
Sentinel 服務熔斷
問題1:當接口觸發(fā)Sentinel配置的流控規(guī)則時,拋出異常,用戶體驗不佳
解決方案:降級處理,展示空數(shù)據(jù)/緩存的舊數(shù)據(jù)
問題2:當A接口需要遠程調用B,而B延遲較高,拖慢了A的服務,用戶體驗差
解決方案:熔斷慢接口,直接停止使用B接口,走降級邏輯
本次練習采用的是OpenFeign遠程調用,使用遠程調用主要有兩種方式
- 方式一:FallbackClass,無法對遠程調用的異常做處理
- 方式二:FallbackFactory,可以對遠程調用的異常做處理,我們一般選擇這種方式。
故使用更為靈活的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("遠程調用ItemClient#queryItemByIds方法出現(xiàn)異常,參數(shù):{}", ids, cause);
// 查詢購物車允許失敗,查詢失敗,返回空集合
return CollUtils.emptyList();
}
@Override
public void deductStock(List<OrderDetailDTO> items) {
log.error("扣減商品庫存失敗!",cause);
// 庫存扣減業(yè)務需要觸發(fā)事務回滾,查詢失敗,拋出異常
throw new BizIllegalException(cause);
}
};
}
}將降級處理邏輯注冊成@Bean
/**
* Feign配置類
*/
public class DefaultFeignConfig {
@Bean
public ItemClientFallback itemClientFallback(){
return new ItemClientFallback();
}
}在遠程調用的注解處配置:失敗處理邏輯的類
/**
* 遠程調用商品服務
*/
@FeignClient(value = "item-service",fallbackFactory = ItemClientFallback.class)
public interface ItemClient {
...
}總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Java 多線程并發(fā)AbstractQueuedSynchronizer詳情
這篇文章主要介紹了Java 多線程并發(fā)AbstractQueuedSynchronizer詳情,文章圍繞主題展開想象的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-06-06
MyBatis中獲取Mysql數(shù)據(jù)庫插入記錄的主鍵值的實現(xiàn)
本文主要介紹了MyBatis中獲取Mysql數(shù)據(jù)庫插入記錄的主鍵值的實現(xiàn),包含了三種實現(xiàn)方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-06-06

