享學課堂特邀作者:老顧
轉載請聲明出處!!!
前言
之前老顧介紹了Sentinel相關的業務介紹,小夥伴們用的怎麼樣呢?今天老顧來介紹另一個話題,就是Sentinel一旦重啓,配置規則就會消失。那肯定是不能夠用在生產環境的,我們需要把規則持久化,老顧來介紹一下nacos裏面。
動態限流規則
Sentinel 動態規則擴展
Sentinel 的理念是開發者只需要關注資源的定義,當資源定義成功後可以動態增加各種流控降級規則。Sentinel 提供兩種方式修改規則:
- 通過 API 直接修改 (loadRules)
- 通過 DataSource 適配不同數據源修改
通過API編碼的方式
FlowRuleManager.loadRules(List<FlowRule> rules); //修改流控規則
DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降級規則
編碼的方式一般僅用於測試和演示,生產上一般通過動態規則源的方式來動態管理規則。
規則管理和推送
官網介紹,規則推送有三種模式:
1)原生模式:API 將規則推送至客戶端並直接更新到內存中;規則保存在內存中,重啓即消失。嚴重不建議用於生產環境。
2)pull模式:即拉模式,客戶端主動向某個規則管理中心定期輪詢拉取規則,這個規則中心可以是 RDBMS、文件 等;實時性不保證,拉取過於頻繁也可能會有性能問題。
3)push模式:即推模式,規則中心統一推送,客戶端通過註冊監聽器的方式時刻監聽變化,比如使用 Nacos、Zookeeper 等配置中心。這種方式有更好的實時性和一致性保證。生產環境下一般採用 push 模式的數據源。
Push模式與DataSource 擴展
生產環境下一般更常用的是push模式的數據源。對於push模式的數據源,如遠程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不應由 Sentinel 客戶端進行,而應該經控制檯統一進行管理,直接進行推送,數據源僅負責獲取配置中心推送的配置並更新到本地。因此推送規則正確做法應該是配置中心控制檯/Sentinel 控制檯 → 配置中心 → Sentinel 數據源 → Sentinel,而不是經 Sentinel 數據源推送至配置中心。這樣的流程就非常清晰了:
本人介紹和nacos相結合的方式。
Nacos
準備環境
因爲同時使用到Nacos和Sentinel Dashboard,所以可以先把Nacos和Sentinel Dashboard啓動起來。
默認配置下啓動後,它們的訪問地址爲:
- Nacos:http://localhost:8848/
- Sentinel Dashboard:http://localhost:8081/
POM依賴
在某個微服務下,引入依賴Spring Cloud Alibaba的Sentinel模塊和Nacos存儲擴展。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
不要忘了 引用sentinel-datasource-nacos哦。
配置
- spring.cloud.sentinel.transport.dashboard:sentinel dashboard的訪問地址
- spring.cloud.sentinel.datasource.ds1-flow.nacos.server-addr:nacos的訪問地址
- spring.cloud.sentinel.datasource.ds1-flow.nacos.groupId:nacos中存儲規則的groupId
- spring.cloud.sentinel.datasource.ds1-flow.nacos.dataId:nacos中存儲規則的dataId
- spring.cloud.sentinel.datasource.ds1-flow.nacos.rule-type:該參數是spring cloud alibaba升級到0.2.2之後增加的配置,用來定義存儲的規則類型。所有的規則類型可查看枚舉類:org.springframework.cloud.alibaba.sentinel.datasource.RuleType,每種規則的定義格式可以通過各枚舉值中定義的規則對象來查看,比如限流規則可查看:com.alibaba.csp.sentinel.slots.block.flow.FlowRule。
在Nacos控制檯,對應的namespace ,新建一個json配置文件:DataID爲scb-content-service-flow-rules,Group爲SENTINEL_GROUP;如下:
爲什麼DataId的後綴爲flow-rules,這個和下面的Sentinel控制檯相結合的時候決定的。配置內容json格式化一下
配置內容:是不是看上去很多信息,也不知道是什麼含義。上面的信息是全部flow流控的配置信息。小夥伴可以看一個簡潔版的
[
{
"resource": "/test",
"limitApp": "default",
"grade": 1,
"count": 10,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
可以看到上面配置規則是一個數組類型,數組中的每個對象是針對每一個保護資源的配置對象,每個對象中的屬性解釋如下:
- resource:資源名,即限流規則的作用對象
- limitApp:流控針對的調用來源,若爲 default 則不區分調用來源
- grade:限流閾值類型(QPS 或併發線程數);0代表根據併發數量來限流,1代表根據QPS來進行流量控制
- count:限流閾值
- strategy:調用關係限流策略
- controlBehavior:流量控制效果(直接拒絕、Warm Up、勻速排隊)
- clusterMode:是否爲集羣模式
啓動scb-content-service應用,註冊到nacos到,打開Sentinel控制檯,可以看到上面nacos新建的限流規則,如下:
注意:
在完成了上面的整合之後,對於接口流控規則的修改就存在兩個地方了:Sentinel控制檯、Nacos控制檯。
這個時候,通過Nacos修改該條規則是可以同步到Sentinel的,但是通過Sentinel控制檯修改或新增卻不可以同步到Nacos。因爲當前版本的Sentinel控制檯不具備同步修改Nacos配置的能力。
而Nacos由於可以通過在客戶端中使用Listener來實現自動更新。所以,在整合了Nacos做規則存儲之後,需要知道在下面兩個地方修改存在不同的效果:
Sentinel控制檯中修改規則:僅存在於服務的內存中,不會修改Nacos中的配置值,重啓後恢復原來的值。Nacos控制檯中修改規則:服務的內存中規則會更新,Nacos中持久化規則也會更新,重啓後依然保持。
下面我們通過對Sentinel Dashboard的改造,使得Nacos與Sentinel可以互相同步限流規則。
Nacos與Sentinel互相同步限流規則
1、控制檯推送規則
Sentinel控制檯推送規則
- 將規則推送到Nacos或其他遠程配置中心
- Sentinel客戶端鏈接Nacos,獲取規則配置;並監聽Nacos配置變化,如發生變化,就更新本地緩存。
控制檯監聽Nacos配置變化,如發生變化就更新本地緩存。從而讓控制檯本地緩存總是和Nacos一致。
2、改造sentinel-dashboard
git官網下載Sentinel 源代碼1.8版本
修改sentinel-dashboard 控制檯模塊的pom.xml,將test註釋掉
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!--<scope>test</scope>-->
</dependency>
修改nacos相關java代碼
找到如下目錄(位於test目錄)
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
將整個目錄拷貝到
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
即把NacosConfig和NacosConfigUtil移植過來;NacosConfig類再做些改造,增加
即初始化nacos的ConfigService對象,這裏需要配置好serverAddr、namespace、以及nacos的用戶名和密碼。
對應的DashboardConfig也需要改造,增加配置項
啓動的時候,需要在jvm參數中加上對應的配置項
增加NacosProvider和NacosPublisher
添加多個規則的的拉取、推送實現類
流控規則拉取和推送
其中原理就是,拉取從nacos的配置文件讀取;在Sentinel控制檯設置流控規則時,就把信息推送到nacos服務中。
其他的規則,很類似,代碼差不多;唯一區別就是 Entity,如下
老顧就不羅列 其他的規則了。
我們再看看NacosConfigUtil
這個就是不同規則的DataId的後綴,如:flow就是以flow-rules爲後綴 現在明白爲什麼上面定義的DataId會有後綴了吧
改造Controller
修改流控規則 FlowControllerV1
添加我們flow的 Publisher 和 Provider
新增推送到nacos的方法
將原來的讀取方法中的 List rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);
改爲List rules = ruleProvider.getRules(app);
將原來設置更新方法中的publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get(5000, TimeUnit.MILLISECONDS);改爲publishRules(entity.getApp());
其他規則的controller是一樣的改造。
修復源碼bug
在降級規則設置時,Sentinel控制檯界面缺失了統計時長的設置,如果不設置,默認是1秒;這個就不是太友好了。我們需要把統計時長放到界面上設置
修改降級界面,在此界面中增加統計時長的屬性
<div class="form-group">
<label class="col-sm-2 control-label">統計時長</label>
<div class="col-sm-4">
<div class="input-group">
<input type='number' min="1" class="form-control highlight-border" ng-model='currentRule.statIntervalMs'
placeholder="統計時長(ms)" />
<span class="input-group-addon">ms</span>
</div>
</div>
</div>
改造完後,界面如下
微服務工程改造增加 sentinel與nacos整合後的依賴後,還需要加上
<!-- sentilen用 nacos 做 持久化-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
配置文件中加入
這樣到此爲止就改造好了
這樣無論是重啓 nacos也好,sentinel也罷,業務工程也罷,都不會丟失sentinel信息。而且可以很好的用Sentinel控制檯進行設置,是不是很酷啊
總結
這篇文章比較長,但非常實用,小夥伴們要仔細看哦。今天就介紹到這裏,謝謝!!!