微服务之Spring cloud alibaba入门——Sentinel篇

微服务之Spring cloud alibaba入门——Sentinel篇

一. 官网简介

Sentinel 官网链接入口

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Setinel的主要特征:
微服务之Spring cloud alibaba入门——Sentinel篇_第1张图片

二. Sentinel控制台安装
  1. 下载jar包

    Sentinel控制台jar包下载地址

  2. 启动运行控制台
    启动控制台:jar -jar 下载的jar包
    浏览器输入:http://localhost:8080/

默认的登录名和密码为都为sentinel

三. Sentinel——初始化工程
  1. 引入pom依赖

    <dependency>
       <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
    dependency>
    
    <dependency>  
        <groupId>com.alibaba.cspgroupId>
        <artifactId>sentinel-datasource-nacosartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-actuatorartifactId>
    dependency>
    
  2. 创建application.yml

    server:
      port: 8512
    spring:
      application:
        name: cloud-sentinel-provider
      cloud:
        nacos:  #注册中心的地址
          discovery:   
            server-addr: localhost:8848	      
        sentinel:
          transport:   #配置仪表盘
            dashboard: localhost:8080
            port: 8719  # 默认为8719,若已被占用则会自动递增
    
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
  3. 修改主启动类

    @SpringBootApplication
    @EnableDiscoveryClient
    public class Sentinel8512Application {
        public static void main(String[] args) {
            SpringApplication.run(Sentinel8512Application.class,args);
        }
    }
    
  4. 创建测试类

    @RestController
    public class FlowLimitController {
    
        @GetMapping(value = "/testA")
        public String testA(){
            return "=======Test A=======";
        }
    
        @GetMapping(value = "/testB")
        public String testB(){
            return "=======Test B=======";
        }
    }
    
  5. 测试监控功能
    启动该项目后,在打开的sentinel仪表盘中仍然看不到任何信息,因为sentinel采用的是懒加载模式,只有请求了某个服务后才会在仪表盘显示相应的服务。在服务器中输入http://localhost:8512/testA或者http://localhost:8512/testB,再次查看sentinel的仪表盘,可以发现服务出现在了列表中,并且打开后在实时监控处可以查看刚刚请求的情况。在簇点链路处也可以看到刚刚的请求路径,并且在该处可以为相应的链路设置流控规则、降级、热点、授权等。

四. Sentinel——流控规则
  • 资源名:唯一名称,默认请求路径

  • 针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default

  • 阈值类型:

    1. QPS:调用该API的QPS达到阈值时进行限流,可以设置流控效果
    2. 线程数:当调用该API的线程数超过阈值时进行限流,不能设置流控效果
  • 流控模式:

    名称 说明
    直接 API达到限流条件时,直接限流并返回错误页面
    关联 当关联的资源达到阈值时,就限流自己
    链路 只记录指定链路上的流量
  • 流控效果

    名称 说明
    快速失败 直接失败,抛异常
    Warm up 根据CodeFactor(冷加载因子,默认为3)的值,从阈值/CodeFactor的值,经过预热时长,才达到设置的QPS阈值。秒杀系统经常使用
    排队等待 请求过多时,让请求匀速的进入后台进行处理。采用漏斗算法,控制流量

    通过仪表盘可以很轻松的配置流控规则,同时也可通过代码配置,代码配置可自行在官网查看。

五. Sentinel——降级规则

Sentinel的熔断降级会在调用链路中某个资源出现不稳定状态时,对这个资源进行限制,让请求快速失败,避免影响其他资源。当资源被降级后,在时间窗口内,所有的对该资源的调用都会被降级。

  • 降级策略
    名称 说明
    RT(平均响应时间) 平均响应时间超出阈值,并且时间窗内的请求数>5,时间窗口后关闭降级
    异常比例 超过一定的异常比例触发,并且时间窗内的请求数>5,时间窗口后关闭降级
    异常数 超过一定的异常数触发,时间窗口后关闭降级
六. SentinelResouce

Sentinel 提供了 @SentinelResource 注解用于定义资源,该注解用于定义降级方法或者处理BlockException的方法。
属性说明:

  • value:用于定义资源的名称
  • blockHandler:对应处理 BlockException 的函数名称,函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException
  • blockHandlerClass:存放了处理 BlockException 的函数
  • fallback:用于在抛出异常的时候提供 fallback 方法处理逻辑
  • fallbackClass:存放了处理java异常的函数
  • exceptionsToIgnore:发生该异常忽略
七. Sentinel——热点规则

热点即经常访问的数据,可以通过热点规则对访问量特别大的数据进行限制。热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。

  • 资源名:该处的资源名必须为@SentinelResource注解中设置的资源名
  • 参数索引:该处的索引为方法中参数的下标,从0开始,通过参数索引的设置,sentinel就知道要限制的参数名称。那么url中有该参数时,若不符合热点规则,会抛出BlockException,那么会对本次访问进行限制,调用block handler的方法。
  • 参数例外项:当参数是某一类型或者值在某一范围内可以单独设定规则

该处配置SentinelResource时,最好配置block handler方法,否则对用户不友好。

代码演示:在测试类添加如下代码,给资源名为test_hotkey的资源添加热点规则,当不符合该规则时,则会调用blockhandler中的方法,可以看到两个函数的返回值相同,参数列表的区别在于处理异常的函数比原函数多一个BlockException函数。

@GetMapping(value = "/testHot")
@SentinelResource(value = "test_hotkey",blockHandler ="handle_C" )
public String testHot(@RequestParam(value = "p1",required = false) String p1,
                      @RequestParam(value = "p2",required = false) String p2){
    return "======testHot======";
}
public String handle_C(String p1, String p2, BlockException exception){
    return "======handle_hot======";
}

定义全局处理类:如果处理异常的方法和原方法同一个类中会显得代码十分臃肿,那么sentinel可以实现将所有的兜底方法定义在另外的一个类中,只要求保证对应处理异常的方法和原方法返回值相同,参数列表多一个BlockException,且都为静态方法。

  1. 定义全局处理类
    public class MyHandler {
        public static String handleEx1(BlockException exception){
            return "handleEx1";
        }
        public static String handleEx2(BlockException exception){
            return "handleEx2";
        }
    }
    
  2. 测试类添加测试代码
    @GetMapping(value = "/testOutHandler")
    @SentinelResource(value = "test_OutHandler",blockHandlerClass = MyHandler.class,blockHandler ="handleEx1" )
    public String testOutHandler(){
        return "======testOutHandler======";
    }
    
八. Sentinel——系统规则
名称 说明
Load自适应 适用于linux和unix系统,一般参考值为CPU核数*2.5
CPU使用率 当系统CPU使用率高过阈值即触发系统保护
平均RT 当所有入口流量的平均响应时间超过阈值触发系统保护
并发线程数 当单台机器上所有入口流量的并发线程数达到阈值触发
入口QPS 当单台机器的所有QPS达到阈值触发保护
九. Sentinel——服务熔断

处理基本的配置和前面讲的blockHandler是相同的,blockhandler能处理不符合规则的请求,但处理不了发生java其他的异常。那么此时就需要用到fallback属性,该属性是配置发生异常后的兜底方法。

@GetMapping("/fallback/{id}")
@SentinelResource(value = "fallback",fallback = "my_fallback",blockHandler = "my_handler")
public String hello(@PathVariable("id") Integer id){
    if (id==4){
        throw new IllegalArgumentException();
    }
    return “调用成功”;
}

public String my_fallback(Integer id){
    return "fallback方法";
}
public String my_handler(Integer id, BlockException exception){
    return "handler方法";
}

该处既配置了熔断方法又配置了blockHandler方法。若此时给该资源定义了热点规则,并且同时传入参数4,那么BlockException和IllegalArgumentException同时发生异常的情况下,会先调用my_handler方法,若符合定义的规则,那就只会调用my_fallback方法来处理IllegalArgumentException异常。

  • sentinel与OpenFeign的整合
    修改application.yml配置文件:feign.sentinel.enabled=true,若不加这一配置则无法配置OpenFeign的兜底方法。以下为OpenFeign的映射和兜底代码。

    @FeignClient(value = "nacos-sentinel-provider",fallback = FallBack.class)
    public interface BalanceService {
        @GetMapping(value = "/balance")
        String nacos_sentinel();
    }
    
    @Component
    public class FallBack implements BalanceService{
        @Override
        public String nacos_sentinel() {
            return "这是feign的兜底方法";
        }
    }
    
十. Sentinel——持久化配置

为什么要进行持久化的配置?
答:重启微服务后,相应的流控规则等都会消失,必须重新配置,那么就需要持久化配置,那么需要一个解决方案,将持久化规则保存起来,可以写入Nacos,也可写入数据库或者文件中。本文用到的是将持久化配置写入Nacos。

  1. 引入依赖

    <dependency>  
        <groupId>com.alibaba.cspgroupId>
        <artifactId>sentinel-datasource-nacosartifactId>
    dependency>
    
  2. 配置持久化

    spring:
      application:
        name: nacos-sentinel-consumer
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
        sentinel:
          transport:
            dashboard: localhost:8080
            port: 8719
          datasource:   # 配置sentinel持久化
            ds1:
              nacos:
                server-addr: localhost:8848
                dataId: nacos-sentinel-consumer
                groupId: DEFAULT_GROUP
                data-type: json
                rule-type: flow
    
  3. sentinel中添加 json 配置文件

    {
        {
            "resource": "/balance",      监控的资源名称
            "limitApp": "default",     来源应用
            "grade": 1,      阈值类型,0为线程数,1为QPS
            "count": 1,     单机阈值
            "strategy": 0,   流控模式, 0直接,1关联,2链路
            "controlBehavior": 0,  流控效果:0快速失败,1warmup,2排队等待
            "clusterMode": false   是否集群
        }
    }
    
    
  4. 验证流控规则持久化
    也是懒加载模式,当某个资源被调用后那么在Sentinel的监控后台就可以看到相应的规则。

十一. 下一篇介绍

对spring cloud alibaba seata介绍,针对的是微服务当中的分布式事务问题。
微服务之Spring cloud alibaba入门——Sentinel篇_第2张图片

你可能感兴趣的:(spring,cloud,alibaba,微服务)