SpringCloudAlibaba微服务实战系列(三)Sentinel1.8.0+流控

SpringCloudAlibaba–Sentinel

Sentinel被称为分布式系统的流量防卫兵,是阿里开源流量框架,从服务限流、降级、熔断等多个纬度保护服务。Sentinel同时提供了简洁易用的控制台,可以看到接入应用的秒级数据,并可以在控制台设置一些规则保护应用。它比Hystrix支持的范围广泛,如Spring Cloud、Dubbo、gRPC都可以整合。集成简单,只需少量的配置和代码就可以完成,容易完成自己定制化的逻辑。

  • 资源是Sentinel最关键的概念,遵循Sentinel API的开发规范定义资源,就能将应用保护起来。

  • 规则可以通过控制面板配置,也可以和资源联合起来,规则可以在控制台修改并且即时生效。

名词解释

  • 限流:对某个资源的访问数量做限制,不让流量一窝蜂地挤进资源访问
  • 降级:即使系统出现问题情况下,也要尽可能提供服务,在可用和完全不可用之间找一个平衡点,如返回友好提示。
  • 熔断:是一种资源访问的状态,熔断状态时,直接拒绝所有的访问,返回友好提示

同类产品对比

基础特性 Sentinel Hystrix Resilience4j
限流 QPS、线程数、调用关系 有限的支持 Rate Limiter
注解支持 支持 支持 支持
动态规则配置 支持多种数据源 支持多种数据源 有限支持数据源
熔断降级策略 平均响应时间、异常比例、异常数 异常比例 平均响应时间、异常比例
控制台 配置各种规则 简单监控 无控制台
常用适配框架 Servlet、SpringCloud、Dubbo、gRPC Servlet、Spring CloudNetflix SpringBoot、Cloud

Resilience4j在国外使用较多,而Hystrix框架已经停止更新进入维护了。

下载和运行

按照笔者之前的笔记,SpringCloudAlibaba是选择的2021.0.4.0版本的,那么可以看下它们之间的版本对应关系

https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aNsTZKUf-1690077185768)(../imgs2/1.png)]

选择这个1.8.5版本即可,到sentinel的下载页面选择即可https://github.com/alibaba/Sentinel/releases

在这里插入图片描述

下载完毕后的jar包启动即可

java -jar sentinel-dashboard-1.8.5.jar

默认的端口是8080,如需更改命令行添加即可

java -jar -Dserver.port=9090 sentinel-dashboard-1.8.5.jar

启动后,打开http://localhost:8080/,账号和密码都是sentinel

在这里插入图片描述

进入后发现没有任何的资源可以进行规则控制。sentinel是采用的懒加载的方式,当使用时才会进行加载。

集成Sentinel

生产者

项目中引入依赖

<dependencies>
    <!-- 服务注册  服务发现需要引入的 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!--健康监控-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!--SpringBoot web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

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

</dependencies>

bootstrap.yml中做配置

server:
  port: 8002
spring:
  application:
    name: provider # 应用名

  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos服务地址
    sentinel:
      transport:
        port: 8719 # 启动http server,并且该服务与Sentinel仪表板进行交互,使sentinel可以控制应用,若端口占用则8719+1依次扫描
        dashboard: 127.0.0.1:8080 # 仪表版访问地址

java controller做个资源

@RestController // @RestController注解是@Controller+@ResponseBody
public class TestController {
    
    

    @RequestMapping("/test")
    public String test() {
    
    
        return "sentinel-provider8002 test()" + RandomUtils.nextInt(0, 1000);
    }
}

消费者

同生产者引入依赖,做好配置,再到controller做个资源

使用RestTemplate+Ribbon做远程调用,添加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

javaConfig配置

@Configuration
public class GenericConfiguration {
    
     // 常规配置类
    @LoadBalanced // 标注此注解后,RestTemplate就具有了客户端负载均衡能力
    @Bean
    public RestTemplate restTemplate(){
    
     // 创建RestTemplate,并交个Spring容器管理
        return new RestTemplate();
    }
}
@RestController // @RestController注解是@Controller+@ResponseBody
public class TestController {
    
    
    private final String SERVER_URL = "http://provider";
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/test")
    public String test() {
    
    
        return restTemplate.getForObject(SERVER_URL + "/test", String.class);
    }
    @RequestMapping("/sentinelTest")
    public String sentinelTest() {
    
    
        return "sentinel-consumer9001 sentinelTest" + RandomUtils.nextInt(0, 1000);
    }

}

完成后,启动项目调用生产者的test接口,然后到sentinel控制台。

curl localhost:9001/test
==> sentinel-provider8002 test()599

在这里插入图片描述

两个服务都出现在了控制台上。

Sentinel常用控制规则

我们需要对接口进行压测,所以使用jmeter吧,到jmter官方下载即可。

流控规则

流控主要是设置QPS或线程数等参数保护应用,针对某个资源的设置,下面操作sentinel控制台设置一些规则。

注意:要先调用接口后,才能添加规则(s加载)

QPS–直接–快速失败

QPS:(Query Per Second)指每秒可处理的请求数

在簇点链路–>列表视图–>到/sentinelTest资源点击流控,阈值选择QPS,单机阈值1,新增。

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fFrataJl-1690077185772)(../imgs2/6.png)]

打开jmeter压测:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C8Z4O7kF-1690077185772)(../imgs2/7.png)]

查看执行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bl7WO34A-1690077185773)(../imgs2/8.png)]

10个请求也就两个成功了,其他都被限流了,直接blocked

QPS–直接–WarmUp

数据预热,即初始请求QPS等于阈值/codeFactor,codeFactor默认值3,经过预热时长1s后单机阈值变为100

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qC7UC1Ql-1690077185773)(../imgs2/9.png)]

压测数量100

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ok19c3YR-1690077185774)(../imgs2/10.png)]

看结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D0Y5NtUv-1690077185774)(../imgs2/11.png)]

前期接口正常返回,当访问量越来越多时,请求QPS=codeFactor(3)时,其他访问直接回绝,经过1s的预热,QPS变成了100后,后面的的所有请求全部正常访问。

QPS–直接–排队等待

让请求全部均匀访问通过,如果请求量超过阈值就等待,若等待超时就返回失败。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rQdwpOeC-1690077185774)(../imgs2/12.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YmAOFAH4-1690077185775)(../imgs2/13.png)]

虽然QPS单机阈值是1,但是我们的超时时间为15s,所以等得起访问全部成功。

QPS–关联–快速失败

如果访问B接口到达了阈值,那么就让A接口返回失败。适用于资源之间有资源竞争或依赖关系。

再写一个接口sentinelTestB

@RequestMapping("/sentinelTestB")
public String sentinelTestB() {
    
    
    return "sentinel-consumer9001 sentinelTestB" + RandomUtils.nextInt(0, 1000);
}

设置规则,要注意当我们重启项目后,这些接口需要重新访问一遍才会出现在sentinel的簇点链路中

在这里插入图片描述

jmter不停访问/sentinelTestB,让B接口超过达阈值,然后在去调用/sentinelTest时直接回绝访问

因为sentinelTestB是没有做流控的,所以请求都是成功的,但是因为访问B接口的请求数是超过QPS阈值的,那么A接口则直接失败。

curl localhost:9001/sentinelTest
Blocked by Sentinel (flow limiting)

线程数–直接

限制处理请求的业务线程数,达到阈值就限流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a1YFoTer-1690077185776)(../imgs2/15.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O7Cja2mh-1690077185776)(../imgs2/16.png)]

可以看到很多请求都被限流了,这个跟服务器的配置有关,当服务器的配置较好时,可以适当将阈值设置的高一些,保证资源的访问情况。

控制台几个关键词

  • 资源名:就是接口的资源,名称唯一即可
  • 针对来源:此资源对调用者进行限流,默认defatult,对所有客户端限流;可填写调用者的spring.application.name指定对某个客户端进行限流。
  • 阈值类型:QPS:每秒能接受的请求数量,线程数:能够使用的业务线程数(服务器内部的线程数)
  • 流控模式:
    • 直接:达到条件,直接执行某个流控效果
    • 关联:如果关联资源达到条件,直接限流自身
    • 链路:记录从入口资源的流量,达到条件也只限流入口资源
  • 流控效果:
    • 快速失败:达到条件,直接返回失败
    • WarmUp:预热,给一个缓冲时间,缓慢增加阈值
    • 排队等待:让系统匀速处理请求,其他请求进入等待,超时后未被处理的请求直接返回失败

猜你喜欢

转载自blog.csdn.net/weixin_45248492/article/details/131876517