1、官方資料
github官網地址:https://github.com/alibaba/Sentinel
wiki:https://github.com/alibaba/Sentinel/wiki/
2、基本使用方式
2.1 Sentinel的初體驗
引入依賴
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel‐core</artifactId>
<version>1.7.1</version>
</dependency>
初始化降級規則
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule(KEY)
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
// Set ratio threshold to 50%.
.setCount(0.5d)
.setStatIntervalMs(30000)
.setMinRequestAmount(50)
// Retry timeout (in second)
.setTimeWindow(10);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
使用降級
Entry entry = null;
try {
entry = SphU.entry(KEY);
throw new RuntimeException("oops");
}catch (Throwable t) {
bizException.incrementAndGet();
// It\'s required to record exception here manually.
Tracer.traceEntry(t, entry);
} finally {
total.addAndGet(1);
if (entry != null) {
entry.exit();
}
}
2.2AOP進階版
引入注解依賴
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel‐annotation‐aspectj</artifactId>
<version>1.7.1</version>
</dependency>
還是規則初始化
Entry entry = null;
try {
entry = SphU.entry(KEY);
throw new RuntimeException("oops");
}catch (Throwable t) {
bizException.incrementAndGet();
// It\'s required to record exception here manually.
Tracer.traceEntry(t, entry);
} finally {
total.addAndGet(1);
if (entry != null) {
entry.exit();
}
}
在對應的方法上加入對應的注解
@Override
@SentinelResource(value = "https://www.cnblogs.com/yulinfu/archive/2020/11/27/hello", fallback = "helloFallback")
public String hello(long s) {
if (s <= 0) {
throw new IllegalArgumentException("invalid arg");
}
return String.format("Hello at %d", s);
}
public String helloFallback(long s, Throwable ex) {
// Do some log here.
ex.printStackTrace();
return "Oops, error occurred at " + s;
}
2.3 spring boot 簇點鏈路版
引入新的jar
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐sentinel</artifactId>
</dependency>
在application.yml中引入dashboard對應的地址
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
啟動dashboard

dashboard有個確定在沒有請求的時候是沒有任何資料的,這里需要觸發一次請求,就看到如下圖的效果

使用起來非常簡便,只需要加入dashboard地址即可
3、從dashboard 看sentinel所具備的功能
3.1流控設定
簇點鏈路 選擇具體的訪問的url地址 然后點擊流控按鈕

資源名稱:為我們介面的url /selectOrderInfoById/1
針對來源:這里是默認的default(標示不針對來源),還有一種情況就是 假設微服務A需要呼叫這個資源,微服務B也需要呼叫這個資源,那么我們就可以單獨的為 微服務A和微服務B進行設定閾值,
閾值型別: 分為QPS和執行緒數 假設閾值為2
QPS型別:只得是每秒鐘訪問介面的次數>2就進行限流
執行緒數:為接受請求該資源 分配的執行緒數>2就進行限流.
流控模式:
①:直接:這種很好理解,就是達到設定的閾值后直接被流控拋出例外 瘋狂的請求這個路徑
②:關聯 業務場景 我們現在有二個api,第一個是保存訂單,第二個是查詢訂單,假設我們希望優先操 作是"保存訂單" ,例如寫介面保存訂單介面達到閥值就會對查詢介面進行限流,相當于是對寫介面的一種保護,

③:鏈路(用法說明,本地實驗沒成功)大家自己研究
流控效果:
①:快速失敗(直接拋出例外) 每秒的QPS 操過1 就直接拋出例外
②:預熱(warmUp)
我們常常會希望系統從空閑狀態到繁忙狀態的切換的時間長一些,即如果系 統在此之前長期處于空閑的狀態,我們希望處理請求的數量是緩步的增多,經過預期的時間以后,到 達系統處理請求個數的最大值,Warm Up(冷啟動,預熱)模式就是為了實作這個目的的,

據圖的請求監控如下

③:排隊等待
這種方式適合用于請求以突刺狀來到,這個時候我們不希望一下子把所有的請求都通過,這樣可能會 把系統壓垮;同時我們也期待系統以穩定的速度,逐步處理這些請求,以起到“削峰填谷”的效果, 而不是拒絕所有請求,

單機閾值:10表示 每秒通過的請求個數是10,那么每隔100ms通過一次請求. 每次請求的最大等待時間為20000=20s,超過20S就丟棄請求,
3.2降級
①rt(平局回應時間)

平均回應時間 (DEGRADE_GRADE_RT):當 1s 內持續進入 5 個請求,對應時刻的平均回應時間(秒 級)均超過閾值(count,以 ms 為單位),那么在接下的時間視窗(DegradeRule 中 的 timeWindow,以 s 為單位)之內,對這個方法的呼叫都會自動地熔斷(拋 出 DegradeException),注意 Sentinel 默認統計的 RT 上限是 4900 ms,超出此閾值的都會算作 4900 ms,若需要變更此上限可以通過啟動配置項 -Dcsp.sentinel.statistic.max.rt=xxx 來配置
②例外比例 (DEGRADE_GRADE_EXCEPTION_RATIO):
當資源的每秒請求量 >= 5,并且每秒例外總數占通過量的比值超過閾值(DegradeRule 中 的 count)之后,資源進入降級狀態,即在接下的時間視窗(DegradeRule 中的 timeWindow,以 s 為單位)之內,對這個方法的呼叫都會自動地回傳,例外比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%,
③例外數 (DEGRADE_GRADE_EXCEPTION_COUNT) :
當資源近 1 分鐘的例外數目超過閾值之后 會進行熔斷,注意由于統計時間視窗是分鐘級別的,若 timeWindow 小于 60s,則結束熔斷狀態后仍可能再 進入熔斷狀態,

3.3 熱點引數:
秒殺業務,比如商城做促銷秒殺,針對蘋果12(商品id=5)進行9.9秒殺活動,那么這個時候,我們去請 求訂單介面(商品id=5)的請求流量十分大,我們就可以通過熱點引數規則來控制 商品id=5的請求的并發量,而其他正常商品的請求不會收到限制,那么 這種熱點引數規則很使用,

4、dashboard與應用程式的簡單互動
4.1原始模式
如果不做任何修改,Dashboard 的推送規則方式是通過 API 將規則推送至客戶端并直接更新到記憶體中:

4.2Pull模式
pull 模式的資料源(如本地檔案、RDBMS 等)一般是可寫入的,使用時需要在客戶端注冊資料源:將對應的讀資料源注冊至對應的 RuleManager,將寫資料源注冊至 transport 的 WritableDataSourceRegistry 中,以本地檔案資料源為例:
public class FileDataSourceInit implements InitFunc {
@Override
public void init() throws Exception {
String flowRulePath = "xxx";
ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>(
flowRulePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {})
);
// 將可讀資料源注冊至 FlowRuleManager.
FlowRuleManager.register2Property(ds.getProperty());
WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(flowRulePath, this::encodeJson);
// 將可寫資料源注冊至 transport 模塊的 WritableDataSourceRegistry 中.
// 這樣收到控制臺推送的規則時,Sentinel 會先更新到記憶體,然后將規則寫入到檔案中.
WritableDataSourceRegistry.registerFlowDataSource(wds);
}
private <T> String encodeJson(T t) {
return JSON.toJSONString(t);
}
}
本地檔案資料源會定時輪詢檔案的變更,讀取規則,這樣我們既可以在應用本地直接修改檔案來更新規則,也可以通過 Sentinel 控制臺推送規則,以本地檔案資料源為例,推送程序如下圖所示:

首先 Sentinel 控制臺通過 API 將規則推送至客戶端并更新到記憶體中,接著注冊的寫資料源會將新的規則保存到本地的檔案中,使用 pull 模式的資料源時一般不需要對 Sentinel 控制臺進行改造,
這種實作方法好處是簡單,不引入新的依賴,壞處是無法保證監控資料的一致性,
4.3push模式
生產環境下一般更常用的是 push 模式的資料源,對于 push 模式的資料源,如遠程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不應由 Sentinel 客戶端進行,而應該經控制臺統一進行管理,直接進行推送,資料源僅負責獲取配置中心推送的配置并更新到本地,因此推送規則正確做法應該是 配置中心控制臺/Sentinel 控制臺 → 配置中心 → Sentinel 資料源 → Sentinel,而不是經 Sentinel 資料源推送至配置中心,這樣的流程就非常清晰了:

我們提供了 ZooKeeper, Apollo, Nacos 等的動態資料源實作,以 ZooKeeper 為例子,如果要使用第三方的配置中心作為配置管理,您需要做下面的幾件事情:
- 實作一個公共的 ZooKeeper 客戶端用于推送規則,在 Sentinel 控制臺配置項中需要指定 ZooKeeper 的地址,啟動時即創建 ZooKeeper Client,
- 我們需要針對每個應用(appName),每種規則設定不同的 path(可隨時修改);或者約定大于配置(如 path 的模式統一為
/sentinel_rules/{appName}/{ruleType},e.g.sentinel_rules/appA/flowRule), - 規則配置頁需要進行相應的改造,直接針對應用維度進行規則配置;修改同個應用多個資源的規則時可以批量進行推送,也可以分別推送,Sentinel 控制臺將規則快取在記憶體中(如
InMemFlowRuleStore),可以對其進行改造使其支持應用維度的規則快取(key 為 appName),每次添加/修改/洗掉規則都先更新記憶體中的規則快取,然后需要推送的時候從規則快取中獲取全量規則,然后通過上面實作的 Client 將規則推送到 ZooKeeper 即可, - 應用客戶端需要注冊對應的讀資料源以監聽變更,可以參考 相關檔案,
從 Sentinel 1.4.0 開始,Sentinel 控制臺提供 DynamicRulePublisher 和 DynamicRuleProvider 介面用于實作應用維度的規則推送和拉取,并提供了相關的示例,Sentinel 提供應用維度規則推送的示例頁面(/v2/flow),用戶改造控制臺對接配置中心后可直接通過 v2 頁面推送規則至配置中心,改造詳情可參考 應用維度規則推送示例,
部署多個控制臺實體時,通常需要將規則存至 DB 中,規則變更后同步向配置中心推送規則,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/228932.html
標籤:其他
上一篇:C#設計模式-橋接模式(Bridge Pattern)
下一篇:sentinel--核心原理篇
