文章目录
sentinel简介
Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。
Sentinel 具有以下特性:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
一些基本概念
资源
所有的监控、限流、熔断等等操作,都是基于“资源”做的。
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
资源在我看来即一个应用内唯一的字符串。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
资源和规则的关系
资源和规则是多对多的关系,一个资源可以配置多个规则,一个规则也可以在多个资源内使用。
当一个资源有多个规则时,多条规则存在与关系,即逐一进行检查,全部通过才算通过。(责任链模式)
springboot项目应用简单实践
由于我们项目中已有监控平台,所以仅仅使用sentinel做一个针对某几个接口的熔断限流的操作
如果要做到全平台监控,建议使用sentinel官方推荐的集成方案,那种方案会对所有url都创建一个资源。
项目环境:springboot
主要有三个类:
- AopConfiguration:切面配置。sentinel可以用注解+切面的形式实施对资源的管理
- ResourceNameDef:资源定义
- RuleDefination:规则定义
pom依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.7.2</version>
</dependency>
<!-- 切面支持 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.7.2</version>
</dependency>
AopConfiguration
/**
* @author Eric Zhao
*/
@Configuration
public class AopConfiguration {
private static final Logger log = LogUtil.getLogger(AopConfiguration.class);
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
log.info("sentinelResourceAspect 装载成功");
return new SentinelResourceAspect();
}
}
ResourceNameDef
/**
* @author xs
* create time: 2020/7/24 14:48
*/
public class ResourceNameDef {
public static final String TEST_GET= "xs.test.get";
}
RuleDefinetion
/**
* @author xs
* create time: 2020/7/24 14:35
*/
@Component
public class RuleDefination {
private static final Logger log = LogUtil.getLogger(RuleDefination.class);
@PostConstruct
public void loadRules() {
initFlowRule(); // 限流策略初始化
initDegradeRule(); // 熔断策略初始化
log.info("sentinel 规则定义完毕!");
}
private void initDegradeRule() {
List<DegradeRule> rules = new ArrayList<DegradeRule>();
DegradeRule rule = new DegradeRule();
rule.setResource(ResourceNameDef.TEST_GET);
// 异常率超过0.1,就认为服务不可用,执行熔断操作
rule.setCount(0.1);
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
rule.setTimeWindow(10);
rule.setMinRequestAmount(20);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
log.info("sentinel 熔断规则定义完毕!");
}
private void initFlowRule() {
List<FlowRule> rules = new ArrayList<FlowRule>();
FlowRule rule = new FlowRule();
rule.setResource(ResourceNameDef.TEST_GET);
// qps上限为1:
rule.setCount(1);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
log.info("sentinel 限流规则定义完毕!");
}
}
对接口限流
定义好资源和规则之后,就可以在项目里使用了。
@RequestMapping("/test")
@RestController
public class TestCtr {
private static final Logger log = LogUtil.getLogger(TestCtr.class);
@SentinelResource(value = ResourceNameDef.TEST_GET,
fallback = "getFallback")
@RequestMapping("/get")
public ResultInfo<Integer> get() {
return ResultInfo.buildSucc(1);
}
public ResultInfo<Integer> getFallback(Throwable t) {
log.info("请求限制了:e={}, msg={}", t.getClass().getName(), t.getMessage());
return ResultInfo.buildFail();
}
}
查看效果
上面的规则定义qps=1,即每秒只能进来一个请求。所以快速请求两次/test/get结果如下:
第一次:
{
"code": 1,
"message": "success"
}
第二次
{
"code": -1,
"message": "fail"
}
此时查看日志会有
2020-07-24 16:47:57.517 [http-nio-8889-exec-4] INFO xs.test.TestCtr - 请求限制了:e=com.alibaba.csp.sentinel.slots.block.flow.FlowException, msg=null
架子初步搭建完毕,可以看到限流时异常为FlowException,可以推断出不同的策略限制,会抛出不同的异常,可以针对处理。
总结
- sentinel源码中有许多demo,使用起来照抄很方便
- 下一步计划是学习限流、熔断策略有哪些。