一、基本簡介
1、概念描述
Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個次元保護服務的穩定性。包括核心的獨立類庫,監控台,豐富的使用場景驗證。(這似乎是阿裡開源元件的一貫作風,極其有特點,且特點很規律)
基本特性圖:
補刀一句
:這種圖很多人可能不在意,但是一般官方給這個圖就是該中間件的基本使用思路,與核心功能點。
2、基礎性概念
- 資源管理
資源是Sentinel元件中的核心概念之一。應用伺服器上腳本,靜态頁面,API接口,檔案圖檔等都可以了解為資源,對于Java開發者而言,API接口就是這裡資源的概念。
- 規則配置
Sentinel元件通過流控規則的配置,來指定允許該資源(API接口)通過的請求次數,IP黑白名單,應用服務等。
- 測試效果
QPS
:每秒查詢率,是一台伺服器每秒能夠處理的查詢次數。
TPS
:每秒處理事務數,事務處理整體傾向于整個過程。
二、架構環境整合
這裡的環境主要整合Nacos注冊中心,Feign服務,Sentinel哨兵,和Sentinel控制台。
1、基本依賴
這裡的依賴需要參考官方文檔,不同的環境使用不同的依賴,這裡主要适配SpringCloud環境,是以使用如下包即可。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
2、控制台面闆
這裡直接從GitHub下載下傳一個控制台服務包即可,也可以自己下載下傳源碼,按照需求修改後自行打包。
java -jar sentinel-dashboard-1.7.1.jar
下載下傳并啟動控制台服務。
3、服務配置
這裡主要是把用到的兩個服務9001和9002連接配接到監控台。
spring:
application:
name: node09-nacos-9001
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
sentinel:
transport:
port: 9001
dashboard: localhost:8080
最下面四行檔案是哨兵控制台的主要配置,注意剛啟動之後控制台是看不到連接配接的,有資源被觸發之後才能看到。(附一張首頁效果圖)
三、流量控制
1、基本描述
流量控制(flow control),其原理是監控應用流量的 QPS 或并發線程數等名額,當達到指定的門檻值時對流量進行控制,以避免被瞬時的流量高峰沖垮,進而保障應用的高可用性。
2、限流規則
限流規則主要由下面幾個因素組成。
- resource:資源名,即限流規則的作用對象,對于Java服務端開發而言就是執行的方法;
- count: 限流門檻值,機關時間内能按照規則通過的請求量;
- grade: 限流門檻值類型,QPS 或并發線程數 ;
- limitApp: 流控限制的指定應用來源,若為default則不區分調用來源;
- strategy: 調用關系限流政策,直連,鍊路等;
- controlBehavior: 流量控制效果,直接拒絕、Warm Up、勻速排隊;
3、基本案例
- 寫死
配置規則
public class FlowRuleConfig {
public static void initFlowQpsRule(String resourceName) {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule(resourceName);
// 修改這裡參數,檢視效果
rule.setCount(100);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
該規則參考上面的限流因素,不難了解。
使用方式
@RequestMapping(value = "/web/getOrder",method = RequestMethod.GET)
public String getOrder (@RequestParam("id") Integer id){
FlowRuleConfig.initFlowQpsRule("getOrder");
Entry entry = null;
try {
// 定義資源,埋點
entry = SphU.entry("getOrder");
// 保護的業務邏輯
return "Order=" + id ;
} catch (Exception e){
e.printStackTrace();
} finally {
if (entry != null){entry.exit();}
}
return "Order Error" ;
}
測試的時候修改規則中count值,測試效果明顯。
- 編碼簡化
SphU.entry中可以設定處理類型,限流門檻值。
@RequestMapping(value = "/web/getState",method = RequestMethod.GET)
public String getState (@RequestParam("id") Integer id){
Entry entry = null;
try {
entry = SphU.entry("getOrder",EntryType.IN,2);
return "state=" + id;
}
catch (BlockException e){
e.printStackTrace();
} finally {
if (entry != null){entry.exit();}
}
return "State Error" ;
}
不過這種模式依舊是代碼入侵嚴重,不太符合現在程式設計的大趨勢。Sentinel支援通過@SentinelResource注解定義資源并配置。
4、測試效果
請求上述的兩個測試接口,之後看控制台中9001服務的簇點鍊路。
可以基于控制台實時配置資源的:流控、降級、熱點、授權等核心功能,服務重新開機之後配置也會重置。
四、服務熔斷降級
1、注解詳解
核心注解
SentinelResource
用于定義資源,并提供可選的異常處理和 fallback 配置項。 @SentinelResource 注解包含以下屬性:
- value
資源名稱,核心概念不能為空;
- entryType
entry 類型,可選項預設為 EntryType.OUT;
- blockHandler
對應處理BlockException的函數名稱,可選項。blockHandler函數通路範圍需要是public,傳回類型需要與原方法相比對,參數類型需要和原方法相比對并且最後加一個額外的參數,類型為BlockException。blockHandler函數預設需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 blockHandlerClass為對應的類的Class對象,注意對應的函數必須為 static 函數,否則無法解析。
- fallback
fallback函數名稱,可選項,用于在抛出異常的時候提供fallback處理邏輯。fallback函數可以針對所有類型的異常(除了 exceptionsToIgnore裡面排除掉的異常類型)進行處理。fallback 函數簽名和位置要求:傳回值類型必須與原函數傳回值類型一緻;方法參數清單需要和原函數一緻,或者可以額外多一個;
注意
:這裡可以這樣了解blockHandler和fallback,fallback處理業務邏輯的異常,服務降級,blockHandler處理sentinel元件控制的阻斷異常。
2、使用案例
9001接口服務
@Service
public class FlowServiceImpl implements FlowService {
@Resource
private JdbcTemplate jdbcTemplate ;
@SentinelResource(value = "getPhone",blockHandler = "exceptionHandler", fallback = "fallback")
@Override
public String getPhone(Integer id) {
String sql = "select phone from d_phone WHERE id="+id ;
Integer.parseInt("hand") ;
return jdbcTemplate.queryForList(sql,String.class).get(0) ;
}
// 降級處理
public String fallback(Integer id) {
return "服務降級,id="+id ;
}
// 異常處理
public String exceptionHandler(Integer id,BlockException be) {
be.printStackTrace();
return "服務抛異常,id="+id ;
}
}
9002請求服務
@RequestMapping(value = "/web/getJdbc",method = RequestMethod.GET)
public String getJdbc () {
return msgFeign.getJdbc() ;
}
3、效果測試
通過控制台配置9001的限流規則,然後刷接口看效果。
注意阻斷異常和業務異常的返參差別。
4、對比Hystrix元件
Hystrix的核心點在于以隔離和熔斷為主的容錯機制,逾時或被熔斷的調用将會快速失敗,并可以提供 fallback 機制;
Sentinel核心點在于流量控制多樣化,熔斷降級服務,系統負載保護,實時監控和控制台;
補刀一句
:對于流量控制類的元件,大部分場景是使用限流,服務降級這兩塊核心功能。
五、源代碼位址
GitHub位址:知了一笑
https://github.com/cicadasmile/spring-cloud-base
GitEE位址:知了一笑
https://gitee.com/cicadasmile/spring-cloud-base