花门楼前见秋草,岂能贫贱相看老。这篇文章主要讲述#私藏项目实操分享#SpringCloud Alibaba Sentinel使用及规则配置相关的知识,希望能为你提供帮助。
Sentinel
是SpringCloud Alibaba
提供的微服务组件,能够从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。与Hystrix
相比,Sentinel
拥有更多的熔断降级维度,更加轻量灵活,并且由于Hystrix
已经停止维护,在生产环境中Sentinel
已经被广泛应用。作为Sentinel
的基础使用,本篇来看一下应该如何进行规则配置。
首先在pom中引入核心依赖:
<
dependency>
<
groupId>
com.alibaba.cloud<
/groupId>
<
artifactId>
spring-cloud-starter-alibaba-sentinel<
/artifactId>
<
/dependency>
在Service中,基于注解的方式定义降级方法和抛出异常时的方法:
@Service
public class QueryService
private static final String KEY="query";
@SentinelResource(value = https://www.songbingjia.com/android/KEY,blockHandler ="blockHandlerMethod",
fallback = "fallbackMethod")
public String query(String name)
if(name.equals("3"))
throw new RuntimeException("3 error");
return "begin query method, name= " + name;
public String blockHandlerMethod(String name, BlockException e)
e.printStackTrace();
return "blockHandlerMethod for Query : " + name;
public String fallbackMethod(String name, Throwable e)
e.printStackTrace();
return "fallbackMethod for Query : " + name;
在上面的示例中,通过
@SentinelResource
注解的blockHandler
属性指定降级方法,通过fallback
属性指定抛出异常时方法。下面,介绍3种规则的定义方式。1、直接编码方式
首先定义一个配置类,用于加载规则。在
Sentinel
中,可以定制5种规则:- 流量控制规则
FlowRule
- 熔断降级规则
DegradeRule
- 访问控制规则
AuthorityRule
- 系统保护规则
SystemRule
- 热点规则
ParamFlowRule
@Component
public class SentinelConfig
private static final String KEY="query";
@PostConstruct
private void init()
initDegradeRule();
initFlowQpsRule();
initSystemRule();
initAuthorityRule();
initParamFlowRule();
//熔断降级规则
private void initDegradeRule()
List<
DegradeRule>
rules=new ArrayList<
>
();
DegradeRule rule=new DegradeRule();
rule.setResource(KEY);
// 80s内调用接口出现 异常 ,次数超过5的时候, 进行熔断
rule.setCount(5);
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
rule.setTimeWindow(80);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
//流量控制规则
private void initFlowQpsRule()
List<
FlowRule>
rules = new ArrayList<
>
();
FlowRule rule = new FlowRule(KEY);
rule.setCount(20);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
//系统保护规则
private void initSystemRule()
List<
SystemRule>
rules = new ArrayList<
>
();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(10);
rules.add(rule);
SystemRuleManager.loadRules(rules);
//黑白名单控制
private void initAuthorityRule()
List<
AuthorityRule>
rules=new ArrayList<
>
();
AuthorityRule rule = new AuthorityRule();
rule.setResource(KEY);
rule.setStrategy(RuleConstant.AUTHORITY_BLACK);
rule.setLimitApp("nacos-consumer");
rules.add(rule);
AuthorityRuleManager.loadRules(rules);
//热点参数规则
private void initParamFlowRule()
ParamFlowRule rule = new ParamFlowRule(KEY)
.setParamIdx(0)
.setCount(20);
ParamFlowItem item = new ParamFlowItem().setObject(String.valueOf("4"))
.setClassType(String.class.getName())
.setCount(2);
rule.setParamFlowItemList(Collections.singletonList(item));
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
在yml中配置
sentinel-dashboard
的地址:spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8088 #sentinel控制台地址
启动
sentinel-dashboard
:java -Dserver.port=8088 -jar sentinel-dashboard-1.8.0.jar
【#私藏项目实操分享#SpringCloud Alibaba Sentinel使用及规则配置】通过调用接口,可以在dashboard的web页面监控到接口的调用情况:
文章图片
查看流控规则,在QPS为2时触发快速失败:
文章图片
查看降级规则,当异常次数超过5次后进行熔断:
文章图片
2、使用本地文件配置数据源
Sentinel
支持多种不同的数据源来配置规则,目前包括以下几种方式:- 文件配置
- Nacos配置
- ZooKeeper配置
- Apollo配置
创建类
FileDataSourceInit
,用于读取配置文件:public class FileDataSourceInit implements InitFunc
private Converter<
String, List<
FlowRule>
>
flowRuleListParser = source ->
JSON.parseObject(source,
new TypeReference<
List<
FlowRule>
>
() );
private Converter<
String, List<
DegradeRule>
>
degradeRuleListParser = source ->
JSON.parseObject(source,
new TypeReference<
List<
DegradeRule>
>
() );
private Converter<
String, List<
SystemRule>
>
systemRuleListParser = source ->
JSON.parseObject(source,
new TypeReference<
List<
SystemRule>
>
() );
private Converter<
String, List<
ParamFlowRule>
>
paramFlowRuleListParser = source ->
JSON.parseObject(source,
new TypeReference<
List<
ParamFlowRule>
>
() );
private Converter<
String, List<
AuthorityRule>
>
authorityRuleListParser = source ->
JSON.parseObject(source,
new TypeReference<
List<
AuthorityRule>
>
() );
@Override
public void init() throws Exception
ClassLoader classLoader = getClass().getClassLoader();
String flowRulePath = URLDecoder.decode(classLoader.getResource("rules/flowRule.json").getFile(), "UTF-8");
String degradeRulePath = URLDecoder.decode(classLoader.getResource("rules/degradeRule.json").getFile(), "UTF-8");
String systemRulePath = URLDecoder.decode(classLoader.getResource("rules/systemRule.json").getFile(), "UTF-8");
String paramFlowRulePath = URLDecoder.decode(classLoader.getResource("rules/paramFlowRule.json").getFile(), "UTF-8");
String authorityRulePath = URLDecoder.decode(classLoader.getResource("rules/authorityRule.json").getFile(), "UTF-8");
// Data source for FlowRule
FileRefreshableDataSource<
List<
FlowRule>
>
flowRuleDataSource = new FileRefreshableDataSource<
>
(
flowRulePath, flowRuleListParser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
// Data source for DegradeRule
FileRefreshableDataSource<
List<
DegradeRule>
>
degradeRuleDataSource
= new FileRefreshableDataSource<
>
(
degradeRulePath, degradeRuleListParser);
DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());
// Data source for SystemRule
FileRefreshableDataSource<
List<
SystemRule>
>
systemRuleDataSource
= new FileRefreshableDataSource<
>
(
systemRulePath, systemRuleListParser);
SystemRuleManager.register2Property(systemRuleDataSource.getProperty());
// Data source for ParamFlowRule
FileRefreshableDataSource<
List<
ParamFlowRule>
>
paramFlowRuleDataSource
= new FileRefreshableDataSource<
>
(
paramFlowRulePath, paramFlowRuleListParser);
ParamFlowRuleManager.register2Property(paramFlowRuleDataSource.getProperty());
// Data source for AuthorityRule
FileRefreshableDataSource<
List<
AuthorityRule>
>
authorityRuleDataSource
= new FileRefreshableDataSource<
>
(
authorityRulePath, authorityRuleListParser);
AuthorityRuleManager.register2Property(authorityRuleDataSource.getProperty());
基于SPI扩展机制,在
resources
下创建META-INF/services
目录,创建文件com.alibaba.csp.sentinel.init.InitFunc
,里面填写上面类的全限定名:com.cn.config.FileDataSourceInit
在
resources
下创建rules
目录,存放配置规则的json文件,以flowRule.json
为例,配置格式如下:["resource":"query",
"limitApp":"default",
"grade":"1",
"count":"2",
"strategy":0,
"controlBehavior":2,
"clusterMode":false]
上面是一个json数组,数组中的每个对象是针对每一个保护资源的配置对象。解释一下上面各参数的意义:
resource:资源名称
limitApp:来源应用
grade:阈值类型,0表示线程数,1表示QPS
count:单机阈值
strategy:流控模式,0表示直接,1表示关联,2表示链路
controlBehavior:流控效果,0表示快速失败,1表示warm up,2表示排队等待
clusterMode:是否集群
其他的规则参数可以参考第一种方式中各Rule的源码中的属性,将首字母变为小写即对应json中的属性名。这样,通过SPI扩展机制就能够将配置文件中的规则加载到内存中了。
3、使用nacos配置数据源
阅读官方文档时发现,官方推荐了使用nacos作为数据源,需要导入nacos存储扩展的依赖:
<
dependency>
<
groupId>
com.alibaba.csp<
/groupId>
<
artifactId>
sentinel-datasource-nacos<
/artifactId>
<
version>
1.8.0<
/version>
<
/dependency>
在yml中添加配置信息,配置nacos作为数据源:
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8088
datasource:
ds:
nacos:
server-addr: 127.0.0.1:8848
group-id: DEFAULT_GROUP
rule-type: flow
data-id: sentinel-demo-getSentinelConfig
data-type: json
数据源参数意义:
ds:数据源名,可随意配置
server-addr: nacos连接地址
group-id: nacos连接的分组
rule-type: 指定路由存储规则
data-id: 读取配置文件的 data-id
data-type: 指定读取配置文件的类型
在nacos的配置列表中添加一条流控规则的配置信息:
文章图片
与项目的
application.yml
中对应,data-id
为sentinel-demo-getSentinelConfig
,group-id
为DEFAULT_GROUP
。刷新dashboard的流控页面,可以看见新建的规则已经被推送过来:
文章图片
如果修改nacos中配置文件的内容,规则会被推送到dashboard中,并且内存中的规则也会随之更新。这样相对于前面的两种配置方式,就实现了不停机更新规则。并且在完成了上面的整合之后,对于规则的修改就可以在
Sentinel-dashboard
、nacos
两个地方同时进行修改了。但是这样仍然存在一些问题,需要注意:
- 通过dashboard设置的规则是存在于内存中的,一旦重启规则就会消失
- 只能通过nacos向dashboard传递规则,而不能将规则写到nacos或本地配置文件中,即规则的传递是单向的
推荐阅读
- 模型改善与泛化(标准化与特征映射)
- tf.nn.conv2d 你不知道的那些事儿
- 推荐学java——MyBatis高级
- #yyds干货盘点#netty系列之:好马配好鞍,为channel选择配套的selector
- vSAN数据恢复异常断电导致上层虚拟机无法启动,vSAN底层数据损坏的数据恢复
- TKE 用户故事 - 作业帮 PB 级低成本日志检索服务
- seata入门介绍与seata-service部署与验证
- Spring认证中国教育管理中心-Apache Geode 的 Spring 数据教程十七
- 手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏01游戏窗口