一、概述
Sentinel是阿里开源的一款面向分布式、多语言异构化服务架构的流量治理组件。
主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
二、核心概念
1、资源
资源是Sentinel中一个非常重要的概念,资源就是Sentinel所保护的对象。
资源可以是一段代码,又或者是一个接口,Sentinel中并没有什么强制规定,但是实际项目中一般以一个接口为一个资源,比如说一个http接口,又或者是rpc接口,它们就是资源,可以被保护。
资源是通过Sentinel的API定义的,每个资源都有一个对应的名称,比如对于一个http接口资源来说,Sentinel默认的资源名称就是请求路径。
2、规则
规则也是一个重要的概念,规则其实比较好理解,比如说要对一个资源进行限流,那么限流的条件就是规则,后面在限流的时候会基于这个规则来判定是否需要限流。
Sentinel的规则分为流量控制规则、熔断降级规则以及系统保护规则,不同的规则实现的效果不一样。
三、Demo
1、基本使用
引入依赖
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId><version>1.8.6</version>
</dependency>
测试代码
public class SentinelSimpleDemo {public static void main(String[] args) {//加载流控规则initFlowRules();for (int i = 0; i < 5; i++) {Entry entry = null;try {entry = SphU.entry("sayHello");//被保护的逻辑System.out.println("访问sayHello资源");} catch (BlockException ex) {System.out.println("被流量控制了,可以进行降级处理");} finally {if (entry != null) {entry.exit();}}}}private static void initFlowRules() {List<FlowRule> rules = new ArrayList<>();//创建一个流控规则FlowRule rule = new FlowRule();//对sayHello这个资源限流rule.setResource("sayHello");//基于qps限流rule.setGrade(RuleConstant.FLOW_GRADE_QPS);//qps最大为2,超过2就要被限流rule.setCount(2);rules.add(rule);//设置规则FlowRuleManager.loadRules(rules);}
}
测试结果
从结果可以看出,当前两次访问sayHello成功之后,qps达到了2,之后再访问就被限流了,失败了。
2、集成Spring
在实际的项目使用中一般不会直接写上面的那段demo代码,而是集成到Spring环境底下。
引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.2.5.RELEASE</version>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>2.2.5.RELEASE</version>
</dependency>
之后提供一个/sayHello接口
@RestController
public class SentinelDemoController {@GetMapping("/sayHello")public String sayHello() throws InterruptedException {return "hello";}
}
配置文件
server:port: 9527spring:application:name: SentinelDemo
Sentinel实现了SpringMVC中的HandlerInterceptor接口,在调用Controller接口之前,会将一个调用接口设置为一个资源,代码如下
而getResourceName方法就是获取资源名,其实就是接口的请求路径,比如前面提供的接口路径是/sayHello,那么资源名就是/sayHello。
测试结果
可以看出规则生效了,接口被Sentinel限流了,至于为什么出现这个提示,是因为Sentinel有默认的处理BlockException的机制,就在前面提到的进入资源的后面。
当然,你也可以自定义处理的逻辑,实现BlockExceptionHandler接口就可以了。
虽然上面这种硬编码规则的方式可以使用,但是在实际的项目中,肯定希望能够基于系统当期那运行的状态来动态调整规则,所以Sentinel提供了一个叫Dashboard应用的控制台,可以通过控制台来动态修改规则。
控制台其实就是一个jar包,可以从Sentinel的github仓库上下载,或者是通过从下面这个地址获取。
之后通过java -jar命令启动就可以了,端口默认8080,浏览器访问http://ip:8080/#/login就可以登录控制台了,用户名和密码默认都是sentinel。
此时服务要接入控制台,只需要在配置文件上加上控制台的ip和端口即可
spring:cloud:sentinel:transport:# 指定控制台的ip和端口dashboard: localhost:8080
项目刚启动的时候控制台默认是没有数据的,需要访问一下接口,之后就有了。
之后就可以看到/sayHello这个资源,后面就可以通过页面设置规则。