github官網地址:https://github.com/alibaba/Sentinel git
wiki:https://github.com/alibaba/Sentinel/wiki/ github
引入依賴spring
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel‐core</artifactId>
<version>1.7.1</version>
</dependency>
初始化降級規則api
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();
}
}
引入註解依賴併發
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel‐annotation‐aspectj</artifactId>
<version>1.7.1</version>
</dependency>
仍是規則初始化app
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();
}
}
在對應的方法上加入對應的註解ide
@Override
@SentinelResource(value = "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;
}
引入新的jar微服務
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐sentinel</artifactId>
</dependency>
在application.yml中引入dashboard對應的地址oop
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
啓動dashboard
dashboard有個肯定在沒有請求的時候是沒有任何數據的,這裏須要觸發一次請求,就看到以下圖的效果
使用起來很是簡便,只須要加入dashboard地址便可
簇點鏈路 選擇具體的訪問的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就丟棄請求。
①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,則結束熔斷狀態後仍可能再 進入熔斷狀態。
秒殺業務,好比商城作促銷秒殺,針對蘋果12(商品id=5)進行9.9秒殺活動,那麼這個時候,咱們去請 求訂單接口(商品id=5)的請求流量十分大,咱們就能夠經過熱點參數規則來控制 商品id=5的請求的併發量。而其餘正常商品的請求不會收到限制。那麼 這種熱點參數規則很使用。
若是不作任何修改,Dashboard 的推送規則方式是經過 API 將規則推送至客戶端並直接更新到內存中:
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 控制檯進行改造。
這種實現方法好處是簡單,不引入新的依賴,壞處是沒法保證監控數據的一致性。
生產環境下通常更經常使用的是 push 模式的數據源。對於 push 模式的數據源,如遠程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操做不該由 Sentinel 客戶端進行,而應該經控制檯統一進行管理,直接進行推送,數據源僅負責獲取配置中心推送的配置並更新到本地。所以推送規則正確作法應該是 配置中心控制檯/Sentinel 控制檯 → 配置中心 → Sentinel 數據源 → Sentinel,而不是經 Sentinel 數據源推送至配置中心。這樣的流程就很是清晰了:
咱們提供了 ZooKeeper, Apollo, Nacos 等的動態數據源實現。以 ZooKeeper 爲例子,若是要使用第三方的配置中心做爲配置管理,您須要作下面的幾件事情:
/sentinel_rules/{appName}/{ruleType}
,e.g. sentinel_rules/appA/flowRule
)。InMemFlowRuleStore
),能夠對其進行改造使其支持應用維度的規則緩存(key 爲 appName),每次添加/修改/刪除規則都先更新內存中的規則緩存,而後須要推送的時候從規則緩存中獲取全量規則,而後經過上面實現的 Client 將規則推送到 ZooKeeper 便可。從 Sentinel 1.4.0 開始,Sentinel 控制檯提供 DynamicRulePublisher
和 DynamicRuleProvider
接口用於實現應用維度的規則推送和拉取,並提供了相關的示例。Sentinel 提供應用維度規則推送的示例頁面(/v2/flow
),用戶改造控制檯對接配置中心後可直接經過 v2 頁面推送規則至配置中心。改造詳情可參考 應用維度規則推送示例。
部署多個控制檯實例時,一般須要將規則存至 DB 中,規則變動後同步向配置中心推送規則。