sentinel
官网:https://sentinelguard.io/zh-cn/docs
一.依赖
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--sentinel end-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.1</version>
</dependency>
二.限流和降级配置
限流和降级分为三种配置方式:
1.硬编码配置:
硬编码配置方式即将限流和降级的规则配置到代码中
/**
* 限流规则
*/
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule1 = new FlowRule();
rule1.setResource("sayHello");
// Set max qps to 20
rule1.setCount(20);
//根据QPS进行限流
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule1.setLimitApp("default");
rules.add(rule1);
FlowRuleManager.loadRules(rules);
}
/**
* 降级规则
*/
private static void initDegradeRule() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule("sayHello")
//按照错误比例进行降级
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)
.setCount(0.7) // Threshold is 70% error ratio
.setMinRequestAmount(100)
// .setStatIntervalMs(30000) // 30s
// 降级发生时恢复超时(以秒为单位)。
.setTimeWindow(10);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
2.控制头台配置
在sentinel的控制台中可以控制限流和降级规则,但是在控制台直接修改规则的话,只接受内存态的规则对象,但更多时候规则存储在文件、数据库或者配置中心当中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zC3ZNUPP-1628669261640)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210309101002046.png)]
3.数据源配置(最常用)
DataSource
扩展常见的实现方式有:
- 拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件,甚至是 VCS 等。这样做的方式是简单,缺点是无法及时获取变更;
- 推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。
Sentinel 目前支持以下数据源扩展:
拉模式扩展
实现拉模式的数据源最简单的方式是继承 AutoRefreshDataSource
抽象类,然后实现 readSource()
方法,在该方法里从指定数据源读取字符串格式的配置数据。比如 基于文件的数据源。
推模式扩展
实现推模式的数据源最简单的方式是继承 AbstractDataSource
抽象类,在其构造方法中添加监听器,并实现 readSource()
从指定数据源读取字符串格式的配置数据。比如 基于 Nacos 的数据源。
public class DataSourcePropertiesConfiguration {
/**
*文件方式配置
**/
private FileDataSourceProperties file;
/**
*nacos方式配置
**/
private NacosDataSourceProperties nacos;
/**
*zookeeper方式配置
**/
private ZookeeperDataSourceProperties zk;
/**
*apollo方式配置
**/
private ApolloDataSourceProperties apollo;
/**
*redis方式配置
**/
private RedisDataSourceProperties redis;
/**
*consul方式配置
**/
private ConsulDataSourceProperties consul;
}
我这里使用nacos进行配置。
spring:
application:
name: dubbo-consumer
cloud:
sentinel:
transport:
#sentinal控制台地址
dashboard: localhost:9999
enabled: true
datasource:
flow-set:
nacos:
#规则类型 FLOW为限流
ruleType: FLOW
#nacos地址
serverAddr: ${spring.cloud.nacos.server-addr}
#nacos配置文件所在的命名空间 这里获取的变量是nacos配置在bootstrap.yml中的参数
namespace: ${spring.cloud.nacos.config.namespace}
#nacos配置文件的dataId 这里获取的变量是nacos配置在bootstrap.yml中的参数
dataId: ${spring.application.name}-sentinel-flow
#nacos配置文件的groupId 这里获取的变量是nacos配置在bootstrap.yml中的参数
groupId: ${spring.cloud.nacos.config.group}
degrade-set:
nacos:
#规则类型 DEGRADE为降级
ruleType: DEGRADE
serverAddr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.config.namespace}
dataId: ${spring.application.name}-sentinel-degrade
groupId: ${spring.cloud.nacos.config.group}
下面为支持的控制规则:
/*
* Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.cloud.sentinel.datasource;
import java.util.Arrays;
import java.util.Optional;
import com.alibaba.cloud.sentinel.datasource.config.AbstractDataSourceProperties;
import com.alibaba.csp.sentinel.slots.block.AbstractRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import org.springframework.util.StringUtils;
/**
* Enum for {@link AbstractRule} class, using in
* {@link AbstractDataSourceProperties#ruleType}.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public enum RuleType {
/**
* flow. 限流
*/
FLOW("flow", FlowRule.class),
/**
* degrade. 熔断降级
*/
DEGRADE("degrade", DegradeRule.class),
/**
* param flow. 热点参数限流
*/
PARAM_FLOW("param-flow", ParamFlowRule.class),
/**
* system.系统自适应保护
*/
SYSTEM("system", SystemRule.class),
/**
* authority. 来源访问控制
*/
AUTHORITY("authority", AuthorityRule.class),
/**
* gateway flow. 网关流量控制
*/
GW_FLOW("gw-flow",
"com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule"),
/**
* api.
*/
GW_API_GROUP("gw-api-group",
"com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition");
/**
* alias for {@link AbstractRule}.
*/
private final String name;
/**
* concrete {@link AbstractRule} class.
*/
private Class clazz;
/**
* concrete {@link AbstractRule} class name.
*/
private String clazzName;
RuleType(String name, Class clazz) {
this.name = name;
this.clazz = clazz;
}
RuleType(String name, String clazzName) {
this.name = name;
this.clazzName = clazzName;
}
public String getName() {
return name;
}
public Class getClazz() {
if (clazz != null) {
return clazz;
}
else {
try {
return Class.forName(clazzName);
}
catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
public static Optional<RuleType> getByName(String name) {
if (StringUtils.isEmpty(name)) {
return Optional.empty();
}
return Arrays.stream(RuleType.values())
.filter(ruleType -> name.equals(ruleType.getName())).findFirst();
}
public static Optional<RuleType> getByClass(Class clazz) {
return Arrays.stream(RuleType.values())
.filter(ruleType -> clazz == ruleType.getClazz()).findFirst();
}
}
nacos中的配置文件
dubbo-consumer-sentinel-degrade
[
{
"resource": "/sayHello",
"limitApp": "default",
"timeWindow":10,
"minRequestAmount": 10,
"grade": 1,
"count": 0.7
}
]
dubbo-consumer-sentinel-flow
[
{
"resource": "/sayHello",
"limitApp": "default",
"grade": 1,
"count": 3,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
这样配置之后,就可以通过修改nacos上的配置文件去实时更新snetinel的规则