Sentinel的理念是只需要開發者關注資源的定義,它默認會對資源進行流控。當然,我們還是需要對定義的資源設置流控規則,主要有兩種方式:
- 通過FlowRuleManager.loadRules()手動加載流控規則。
- 在Sentinel Dashboard上針對資源動態創建流控規則。
針對第一種方式,如果接入Sentinel Dashboard,那么同樣支持動態修改流控規則,但是基於Sentinel Dashboard所配置的流控規則,都是保存在內存中的,一旦應用重啟,這些規則都會被清除。為了解決這個問題,Sentinel提供了動態數據源支持。
目前,Sentinel支持Consul、Zookeeper、Redis、Nacos、Apollo、etcd等數據源的擴展,接下來通過一個案例展示Spring Cloud Sentinel集成Nacos實現動態流控規則,步驟如下:
應用配置
第一步:在Spring Cloud應用的pom.xml
中引入Spring Cloud Alibaba的Sentinel模塊和Nacos存儲擴展:
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2021.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-datasource-nacos -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.2</version>
</dependency>
</dependencies
第二步:在Spring Cloud應用中添加配置信息:
server:
port: 8080
spring:
application:
name: spring-cloud-alibaba
cloud:
sentinel:
transport:
dashboard: sentinel:8080
eager: true #服務注啟動,直接注冊到dashboard
datasource:
ds:
nacos:
server-addr: nacos-headless:8848
dataId: my-sentinel
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
rule-type: flow #定義存儲的規則類型,該參數是spring cloud alibaba升級到0.2.2之后增加的配置
data-type: json
spring.cloud.sentinel.transport.dashboard
:sentinel dashboard的訪問地址,根據上面准備工作中啟動的實例配置spring.cloud.sentinel.datasource.ds.nacos.server-addr
:nacos的訪問地址,,根據上面准備工作中啟動的實例配置spring.cloud.sentinel.datasource.ds.nacos.groupId
:nacos中存儲規則的groupIdspring.cloud.sentinel.datasource.ds.nacos.dataId
:nacos中存儲規則的dataId
注意:Spring Cloud Alibaba的Sentinel整合文檔中有一些小問題,比如:並沒有spring.cloud.sentinel.datasource.ds2.nacos.rule-type
這個參數。可能是由於版本迭代更新,文檔失修的緣故。讀者在使用的時候,可以通過查看org.springframework.cloud.alibaba.sentinel.datasource.config.DataSourcePropertiesConfiguration
和org.springframework.cloud.alibaba.sentinel.datasource.config.NacosDataSourceProperties
兩個類來分析具體的配置內容,會更為准確。
第三步:創建應用主類
@RestController
@RequestMapping("/sentinel")
public class SentinelController {
@Autowired
private SentinelService sentinelService;
@GetMapping("/get")
public String get() {
return sentinelService.getBody();
}
}
@Service
public class SentinelService {
@SentinelResource(value = "get",blockHandler = "getBodyBack")
public String getBody() {
// 真正的業務邏輯
// 被保護的資源
return "給你我的肉體哦";
}
public String getBodyBack(BlockException blockException) {
return "降級了";
}
}
第四步:Nacos中創建限流規則的配置,比如:
其中:Data ID
、Group
就是上面第二步中配置的內容。配置格式選擇JSON,並在配置內容中填入下面的內容:
[
{
"resource": "get",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
可以看到上面配置規則是一個數組類型,數組中的每個對象是針對每一個保護資源的配置對象,每個對象中的屬性解釋如下:
- resource:資源名,即限流規則的作用對象
- limitApp:流控針對的調用來源,若為 default 則不區分調用來源
- grade:限流閾值類型(QPS 或並發線程數);
0
代表根據並發數量來限流,1
代表根據QPS來進行流量控制 - count:限流閾值
- strategy:調用關系限流策略
- controlBehavior:流量控制效果(直接拒絕、Warm Up、勻速排隊)
- clusterMode:是否為集群模式
第五步:啟動應用
此時,在Sentinel Dashboard中就可以看到當前我們啟動的alibaba-sentinel-datasource-nacos
服務。點擊左側菜單中的流控規則,可以看到已經存在一條記錄了
注意
Sentinel控制台不具備同步修改Nacos配置的能力,而Nacos由於可以通過在客戶端中使用Listener來實現自動更新。所以,在整合了Nacos做規則存儲之后,需要知道在下面兩個地方修改存在不同的效果:
- Sentinel控制台中修改規則:僅存在於服務的內存中,不會修改Nacos中的配置值,重啟后恢復原來的值。
- Nacos控制台中修改規則:服務的內存中規則會更新,Nacos中持久化規則也會更新,重啟后依然保持。