Sentinel 實戰-限流篇
逅弈 轉載請註明原創出處,謝謝!
系列文章
Sentinel 原理-全解析
Sentinel 原理-呼叫鏈
Sentinel 原理-滑動視窗
Sentinel 原理-實體類
Sentinel 實戰-控制檯篇
Sentinel 實戰-規則持久化
Sentinel 實戰-叢集限流篇
Sentinel 系列教程,現已上傳到 github 和 gitee 中:
- GitHub:https://github.com/all4you/sentinel-tutorial
- Gitee:https://gitee.com/all_4_you/sentinel-tutorial
我們已經知道了 Sentinel 的三大功能:限流
降級
系統保護
。現在讓我們來了解下具體的使用方法,以限流來演示具體的步驟。
引入依賴
首先肯定是要先引入需要的依賴,如下所示:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>x.y.z</version>
</dependency>
這裡的版本號 x.y.z 可以根據需要自行選擇,我選擇的是截至目前為止的最新版:1.4.0。
定義資源
假設我們有一個 UserService :
public class UserService {
/**
* 根據uid獲取使用者資訊
* @param uid uid
* @return 使用者資訊
*/
public User getUser(Long uid){
// 業務程式碼
User user = new User();
user.setUid(uid);
user.setName("user-" + uid);
return user;
}
public static class User {
private Long uid;
private String name;
// 省略getter、setter
}
}
現在我們要對 getUser 方法進行限流,那首先我們要定義一個資源,在 sentinel 中資源是抽象出來做具體的操作的,用資源來保護我們的程式碼和服務。
使用者只需要為受保護的程式碼或服務定義一個資源,然後定義規則就可以了,剩下的都交給sentinel來處理了。定義完資源後,就可以通過在程式中埋點來保護你自己的服務了,埋點的方式有兩種:丟擲異常和返回布林值。
下面我用丟擲異常的方式進行埋點:
// 定義的資源
public static final String USER_RES = "userResource";
public User getUser(Long uid){
Entry entry = null;
try {
// 流控程式碼
entry = SphU.entry(USER_RES);
// 業務程式碼
User user = new User();
user.setUid(uid);
user.setName("user-" + uid);
return user;
}catch(BlockException e){
// 被限流了
System.out.println("[getUser] has been protected! Time="+System.currentTimeMillis());
}finally {
if(entry!=null){
entry.exit();
}
}
return null;
}
除了通過跑出異常的方式定義資源外,返回布林值的方式也是一樣的,這裡不具體展開了。
PS:如果你不想對原有的業務程式碼進行侵入,也可以通過註解 SentinelResource 來進行資源埋點。
定義規則
定義完資源後,就可以來定義限流的規則了,但是我們需要對流控規則做個詳細的瞭解,以便更好的進行限流的操作,流控的規則對應的是 FlowRule。
一條FlowRule有以下幾個重要的屬性組成:
- resource: 規則的資源名
- grade: 限流閾值型別,qps 或執行緒數
- count: 限流的閾值
- limitApp: 被限制的應用,授權時候為逗號分隔的應用集合,限流時為單個應用
- strategy: 基於呼叫關係的流量控制
- controlBehavior:流控策略
前三個屬性比較好理解,最後三個比較難理解,讓我們來詳細看下最後三個屬性:
limitApp
首先讓我們來看下limitApp,從字面上看是指要限制哪個應用的意思,主要是用於根據呼叫方進行流量控制。
他有三種情況可以選擇:
- default
表示不區分呼叫者,來自任何呼叫者的請求都將進行限流統計。
- {some_origin_name}
表示針對特定的呼叫者,只有來自這個呼叫者的請求才會進行流量控制。
例如:資源 NodeA
配置了一條針對呼叫者 caller1 的規則,那麼當且僅當來自 caller1 對 NodeA
的請求才會觸發流量控制。
- other
表示除 {some_origin_name} 以外的其餘呼叫方的流量進行流量控制。
例如:資源 NodeA
配置了一條針對呼叫者 caller1 的限流規則,同時又配置了一條呼叫者為 other 的規則,那麼任意來自非 caller1 對 NodeA
的呼叫,都不能超過 other 這條規則定義的閾值。
strategy
基於呼叫關係的流量控制,也有三種情況可以選擇:
- STRATEGY_DIRECT
根據呼叫方進行限流。ContextUtil.enter(resourceName, origin) 方法中的 origin 引數標明瞭呼叫方的身份。
如果 strategy 選擇了DIRECT ,則還需要根據限流規則中的 limitApp 欄位根據呼叫方在不同的場景中進行流量控制,包括有:”所有呼叫方“、”特定呼叫方origin“、”除特定呼叫方origin之外的呼叫方“。
- STRATEGY_RELATE
根據關聯流量限流。當兩個資源之間具有資源爭搶或者依賴關係的時候,這兩個資源便具有了關聯,可使用關聯限流來避免具有關聯關係的資源之間過度的爭搶。
比如對資料庫同一個欄位的讀操作和寫操作存在爭搶,讀的速度過高會影響寫得速度,寫的速度過高會影響讀的速度。
舉例來說:read_db 和 write_db 這兩個資源分別代表資料庫讀寫,我們可以給 read_db 設定限流規則來達到寫優先的目的:設定 FlowRule.strategy 為 RuleConstant.STRATEGY_RELATE,同時設定 FlowRule.refResource 為 write_db。這樣當寫庫操作過於頻繁時,讀資料的請求會被限流。
- STRATEGY_CHAIN
根據呼叫鏈路入口限流。假設來自入口 Entrance1 和 Entrance2 的請求都呼叫到了資源 NodeA,Sentinel 允許根據某個入口的統計資訊對資源進行限流。
舉例來說:我們可以設定 FlowRule.strategy 為 RuleConstant.CHAIN,同時設定 FlowRule.refResource 為 Entrance1 來表示只有從入口 Entrance1 的呼叫才會記錄到 NodeA 的限流統計當中,而對來自 Entrance2 的呼叫可以放行。
controlBehavior
流控策略,主要是發生攔截後具體的流量整形和控制策略,目前有三種策略,分別是:
- CONTROL_BEHAVIOR_DEFAULT
這種方式是:直接拒絕,該方式是預設的流量控制方式,當 qps 超過任意規則的閾值後,新的請求就會被立即拒絕,拒絕方式為丟擲FlowException。
這種方式適用於對系統處理能力確切已知的情況下,比如通過壓測確定了系統的準確水位。
- CONTROL_BEHAVIOR_WARM_UP
這種方式是:排隊等待 ,又稱為 冷啟動。該方式主要用於當系統長期處於低水位的情況下,流量突然增加時,直接把系統拉昇到高水位可能瞬間把系統壓垮。
通過"冷啟動",讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮的情況。
- CONTROL_BEHAVIOR_RATE_LIMITER
這種方式是:慢啟動,又稱為 勻速器模式。這種方式嚴格控制了請求通過的間隔時間,也即是讓請求以均勻的速度通過,對應的是漏桶演算法。
這種方式主要用於處理間隔性突發的流量,例如訊息佇列。想象一下這樣的場景,在某一秒有大量的請求到來,而接下來的幾秒則處於空閒狀態,我們希望系統能夠在接下來的空閒期間逐漸處理這些請求,而不是在第一秒直接拒絕多餘的請求。
具體的 FlowRule 可以用下面這張圖表示:
規則定義好了之後,啟動應用後,就會自動對我們的業務程式碼進行保護了,當然實際生產環境中不可能通過硬編碼的方式來定義規則的,sentinel 為我們提供了 DataSource 介面,通過實現該介面可以自定義規則的儲存資料來源。
通過 DataSource 介面可以有很多種方式對規則進行持久化,例如:
- 整合動態配置系統,如 ZooKeeper、Nacos 等,動態地實時重新整理配置規則
- 結合 RDBMS、NoSQL、VCS 等來實現該規則
- 配合 Sentinel Dashboard 使用
本篇文章不對規則的持久化做具體的介紹,本篇文章主要是實現一個簡單的限流的例子的接入。
PS:DateSource 介面在後期已經被拆成 ReadableDataSource 和 WritableDataSource 介面了。
檢視日誌
我們通過一個Spring Boot專案來啟動,其中 UserService 作為一個專案中一個具體的服務,專案啟動好之後,會在 ${userhome}/logs/csp/ 目錄下建立一個 sentinel-record.log.${date} 的日誌檔案,該檔案會記錄 sentinel 的重要的行為,我本地的日誌檔案如下所示:
從上圖中可以看到,除了 sentinel-record 之外,還有 sentinel-exception 檔案,從命名上就可以知道這個檔案是記錄 sentinel 執行過程中出現的異常的。
讓我們開啟 sentinel-record.log.2019-01-02.0 的檔案看下具體的內容:
sentinel-record 日誌中會記錄載入好的規則等資訊,具體的實時統計日誌會在另一個 叫 xx-metrics.log.${date} 的檔案中。
檢視統計效果
首先我們要訪問一下我們的服務,觸發了 sentinel 的限流規則後,才會生成具體的統計檔案。
可以發現該方法成功返回了,現在讓我們來看看 ~/logs/csp/ 目錄下生成的統計檔案,如下圖所示:
該統計檔案的命名方式是 ${appName}-metrics.log.${date} ,其中 ${appName} 會優先獲取的系統引數 project.name 的值,如果獲取不到會從啟動引數中獲取,具體的獲取方式在 AppNameUtil 類中。
我們開啟 lememo-retircs 檔案,看到如下的資訊:
可以看到我們請求了很多次該資源後,sentinel 把每秒的統計資訊都列印出來了,用 | 來分隔不同的引數,一共有8個引數,從左至右分別是:
可以看到我們的請求都已經成功通過了,現在我們把規則中設定的 count 閾值改為1,然後重啟服務後,再次請求該服務,然後再次開啟 lememo-metrics 檔案,如下圖所示:
可以看到每秒中只有1個請求通過了,其他的都被 block 了,再看我們在程式碼中列印的日誌:
本篇文章通過一個例子對 sentinel 的限流進行了實戰,瞭解了規則的詳細作用,也知道通過 sentinel 列印的日誌來檢視執行過程中狀態。
但是這種方式比較原始,不管是建立規則,還是檢視日誌,下篇文章我將通過 sentinel 自帶的控制檯帶大家瞭解具體的作用。
相關文章
- Sentinel 實戰-控制檯篇
- Spring Cloud Gateway 整合阿里 Sentinel閘道器限流實戰!SpringCloudGateway阿里
- 微服務實戰(八)整合Sentinel閘道器服務限流功能 SpringCloud GateWay + Sentinel + Nacos微服務SpringGCCloudGateway
- Spring Cloud Alibaba | Sentinel: 服務限流基礎篇SpringCloud
- Spring Cloud Alibaba | Sentinel: 服務限流高階篇SpringCloud
- Sentinel實戰
- Sentinel實現限流,竟是如此的簡單!
- Spring Cloud Alibaba:Sentinel實現熔斷與限流SpringCloud
- Sentinel限流熔斷降級
- Sentinel入門到實操 (限流熔斷降級)
- 六、Alibaba sentinel之限流原理分析
- Spring Cloud Alibaba基礎教程:使用Sentinel實現介面限流SpringCloud
- Spring Cloud Gateway限流實戰SpringCloudGateway
- Sentinel分散式限流元件,SpringCloud Alibaba整合分散式元件SpringGCCloud
- Spring Cloud Alibaba系列(五)sentinel實現服務限流降級SpringCloud
- 聊聊自定義SPI如何與sentinel整合實現熔斷限流
- Sentinel 實戰-規則持久化持久化
- SpringCloud微服務實戰——搭建企業級開發框架(十四):整合Sentinel高可用流量管理框架【限流】SpringGCCloud微服務框架
- SpringCloud Alibaba系列(三) Sentinel熱點引數限流SpringGCCloud
- 阿里限流神器Sentinel奪命連環 17 問?阿里
- 遊戲推薦業務中基於 sentinel 的動態限流實踐遊戲
- 阿里開源限流元件 Sentinel 叢集流控全解析阿里元件
- 阿里巴巴開源限流系統 Sentinel 全解析阿里
- Sentinel併發限流不精確-之責任鏈
- Redis Sentinel-深入淺出原理和實戰Redis
- spring cloud alibaba系列(二)Sentinel應用的限流管理SpringCloud
- 阿里巴巴開源限流元件Sentinel初探之整合Gateway阿里元件Gateway
- 10000字,圖解分散式系統限流平臺Sentinel圖解分散式
- Sentinel限流之快速失敗和漏桶演算法演算法
- 令牌桶、漏斗、冷啟動限流在sentinel的應用
- 更好用的叢集限流功能,Sentinel 釋出 v1.4.2
- python:實戰篇Python
- spring cloud gateway 之限流篇SpringCloudGateway
- 流量治理神器-Sentinel的限流模式,選單機還是叢集?模式
- 基於Sentinel自研元件的系統限流、降級、負載保護最佳實踐探索元件負載
- 阿里巴巴開源限流降級神器Sentinel大規模生產級應用實踐阿里
- 一篇搞定Sentinel-搭建Spring Cloud Alibaba服務元件Sentinel實現服務資源控制SpringCloud元件
- 實戰篇——CSRF漏洞pikachu靶場實戰