当前位置: 首页>后端>正文

SpringCloudAlibaba之Sentinel介绍

简介

Sentinel是阿里开源的一款面向分布式、多语言异构化服务架构的流量治理组件。
主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性

核心概念

要想理解一个新的技术,那么首先你得理解它的一些核心概念

资源

资源是Sentinel中一个非常重要的概念,资源就是Sentinel所保护的对象。

资源可以是一段代码,又或者是一个接口,Sentinel中并没有什么强制规定,但是实际项目中一般以一个接口为一个资源,比如说一个http接口,又或者是rpc接口,它们就是资源,可以被保护。

资源是通过SentinelAPI定义的,每个资源都有一个对应的名称,比如对于一个http接口资源来说,Sentinel默认的资源名称就是请求路径。

规则

规则也是一个重要的概念,规则其实比较好理解,比如说要对一个资源进行限流,那么限流的条件就是规则,后面在限流的时候会基于这个规则来判定是否需要限流。

Sentinel规则分为流量控制规则、熔断降级规则以及系统保护规则,不同的规则实现的效果不一样。

入门Demo

测试代码


    public static void testSentinel() {
        //加载流控规则
        initFlowRules();

        for (int i = 0; i < 5; i++) {
            Entry entry = null;
            try {
                entry = SphU.entry("sayHello");
                //被保护的逻辑
                log.info("访问sayHello资源");
            } catch (BlockException ex) {
                log.error("被流量控制了,可以进行降级处理");
            } 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);
    }

解释一下上面这段代码的意思
}
解释一下上面这段代码的意思

  • initFlowRules:方法就是加载一个限流的规则,这个规则作用于sayHello这个资源,基于qps限流,当qps超过2之后就会触发限流。
  • SphU.entry("sayHello"):这行代码是Sentinel最最核心的源码,这行代码表面看似风平浪静,实则暗流涌动。这行代码表明接下来需要访问某个资源(参数就是资源名称),会去检查需要被访问的资源是否达到设置的流控、熔断等规则。对于demo来说,就是检查sayHello这个资源是否达到了设置的流量控制规则。
  • catch BlockException:也很重要,当抛出BlockException这个异常,说明触发了一些设置的保护规则,比如限流了,这里面就可以进行降级操作。
  • log.info("访问sayHello资源"):这行代码表面是一个打印语句,实则就是前面一直在说的需要被保护的资源。

所以上面这段代码的整体意思就是对 sayHello这个需要访问的资源设置了一个流控规则,规则的内容是当qps到达2的时候触发限流,之后循环5次访问sayHello这个资源,在访问之前通过SphU.entry("sayHello")这行代码进行限流规则的检查,如果达到了限流的规则的条件,会抛出BlockException。

集成Spring

在实际的项目使用中一般不会直接写上面的那段demo代码,而是集成到Spring环境底下。

引入依赖

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

Spring中资源规则

那么那前面提到的资源和对应的规则去哪了?
前面在说资源概念的时候,提到 Sentinel 中默认一个http接口就是一个资源,并且资源的名称就是接口的请求路径。而真正的原因是Sentinel实现了SpringMVC中的HandlerInterceptor接口,在调用Controller接口之前,会将一个调用接口设置为一个资源,代码如下

SpringCloudAlibaba之Sentinel介绍,第1张
Sentinel拦截器

getResourceName方法就是获取资源名,其实就是接口的请求路径,比如前面提供的接口路径是/sayHello,那么资源名就是/sayHello
再后面的代码就是调用上面demo中提到表面风平浪静,实则暗流涌动的SphU.entry(..)方法,检查被调用的资源是否达到了设置的规则。

好了,既然资源默认是接口,已经有了,那么规则呢?
规则当然可以按照第一个demo的方式来做,比如在Controller接口中加载,代码如下。

@RestController
public class SentinelDemoController {

    static {
        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);
    }

    @GetMapping("/sayHello")
    public String sayHello() throws InterruptedException {
        return "hello";
    }

}

此时启动项目,在浏览器输入链接,疯狂快速使劲地多点几次,就出现下面这种情况

SpringCloudAlibaba之Sentinel介绍,第2张
被限流了

可以看出规则生效了,接口被Sentinel限流了,至于为什么出现这个提示,是因为Sentinel有默认的处理BlockException的机制,就在前面提到的进入资源的后面。
SpringCloudAlibaba之Sentinel介绍,第3张
抛出异常

当然,也可以自定义处理的逻辑,实现BlockExceptionHandler接口就可以了。

Sentinel控制台

虽然上面这种硬编码规则的方式可以使用,但是在实际的项目中,肯定希望能够基于系统当期那运行的状态来动态调整规则,所以Sentinel提供了一个叫Dashboard应用的控制台,可以通过控制台来动态修改规则。


SpringCloudAlibaba之Sentinel介绍,第4张
控制台修改规则

控制台其实就是一个jar包,可以从Sentinel的github仓库上下载。
之后通过java -jar命令启动就可以了,端口默认8080,浏览器访问 http://ip:8080/#/login就可以登录控制台了,用户名和密码默认都是 sentinel。
java -Dserver.port=8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.1.jar

那么问题来了:默认的用户名和密码在生产环境上肯定不能用,如何修改呢?
从 Sentinel 1.6.0 起 sentinel 已经支持自定义用户名和密码了,只需要在执行jar命令时指定即可,命令如下:

启动命令:

java -Dserver.port=8080
     -Dcsp.sentinel.dashboard.server=localhost:8080
     -Dproject.name=sentinel-dashboard
     -Dsentinel.dashboard.auth.username=admin 
     -Dsentinel.dashboard.auth.password=123 
     -jar sentinel-dashboard-1.7.1.jar
     

用户可以通过如下参数进行配置:

  • -Dserver.port:指定启动的端口,默认8080
  • -Dproject.name:指定本服务的名称
  • -Dcsp.sentinel.dashboard.server:指定sentinel控制台的地址,用于将自己注册进入实现监控自己
  • -Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel;
  • -Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为 sentinel;
  • -Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;

此时服务要接入控制台,只需要在配置文件上加上控制台的ip和端口即可

spring:
  cloud:
    sentinel:
     # 取消控制台懒加载
      eager: true
      transport:
        # 指定控制台的ip和端口
        dashboard: localhost:8080

项目刚启动的时候控制台默认是没有数据的,需要访问一下接口,之后就有了。


SpringCloudAlibaba之Sentinel介绍,第5张
控制台信息

之后就可以看到/sayHello这个资源,后面就可以通过页面设置规则。

防坑指南

新版的Sentinel只需要在VM启动参数的添加参数即可,不需要在属性文件里配置对应的地址,如图所示:


SpringCloudAlibaba之Sentinel介绍,第6张
配置启动参数

https://www.xamrdz.com/backend/3uj1929121.html

相关文章: