SpringCloud Alibaba Sentinel 服务限流熔断降级 - 基于dashboard方式配制

Posted 小毕超

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud Alibaba Sentinel 服务限流熔断降级 - 基于dashboard方式配制相关的知识,希望对你有一定的参考价值。

一、Sentinel

在上两篇博客中我们基于程序配制的方式演示了Sentinel 的功能,相信大家应该对 Sentinel 已经有了更深的认识,本篇接着上篇继续,使用便捷化的dashboard控制台进行实现,可以实现无需重启服务的情况下动态修改策略规则。下面是上篇文章的地址:

Sentinel 熔断降级:https://blog.csdn.net/qq_43692950/article/details/122161209

Sentinel 流量控制:https://blog.csdn.net/qq_43692950/article/details/122161209

在开始前,需要下载官方的 dashboard jar 包,下载地址:

https://github.com/alibaba/Sentinel/releases


下载好后,在同级目录编写一个start.bat启动脚本,写入以下内容:

java -Dserver.port=8180 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.2.jar

双击start.bat启动 dashboard 程序,然后浏览器访问 http://localhost:8180/ 即可进入控制台页面,默认用户名密码为 sentinel


二、服务连接至 dashboard

上面dashboard 就已经搭建成功了,下面就需要将我们的服务注册到dashboard 中,下面新建一个SpringBoot的Module,在pom中引入依赖:

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

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

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

修改application.yml配制文件:

server:
  port: 8080

spring:
  application:
    name: cloudalibaba-sentinel
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.40.130:8848 #nacos地址
    sentinel:
      transport:
        port: 8719 #跟 sentinel 控制台交流的端口,随意指定一个未使用的端口即可默认是8719
        dashboard: 127.0.0.1:8180 # 指定 sentinel 控制台地址。
      eager: true #当服务启动时是否与sentinel建立链接
      web-context-unify: false #关闭 URL PATH 聚合
      
management:
  endpoints:
    web:
      exposure:
        include: '*'

主启动类:

@SpringBootApplication
@EnableDiscoveryClient
public class SentinelApplication 
    public static void main(String[] args) 
        SpringApplication.run(SentinelApplication.class, args);
    

启动服务,查看Sentinel控制台:

已经连接到 dashboard中了

三、流控规则

QPS的流控规则


下面编写测试接口,并指定资源为mylimit

@RestController
@RequestMapping("/limit")
public class TestController 

    @SentinelResource(value = "mylimit",
            blockHandler = "blockHandler")
    @GetMapping("/testLimit")
    public ResponseTemplate limit()
        return ResSuccessTemplate.builder().build();
    

    public ResponseTemplate blockHandler(BlockException exception)
        return ResFailTemplate.builder().code(406).message("接口限流!").build();
    

新建QPS的限流规则:

如果是看过上两篇博客,对这些参数就非常熟悉了。

下面浏览器访问:http://localhost:8080/limit/testLimit,快速点击就可以看到下面的效果:

线程池的流控规则

修改接口:

@RestController
@RequestMapping("/limit")
public class TestController 

    @SentinelResource(value = "mylimit",
            blockHandler = "blockHandler")
    @GetMapping("/testLimit")
    public ResponseTemplate limit() throws InterruptedException 
        TimeUnit.SECONDS.sleep(5);
        return ResSuccessTemplate.builder().build();
    

    public ResponseTemplate blockHandler(BlockException exception)
        return ResFailTemplate.builder().code(406).message("接口限流!").build();
    

开三个窗口,访问上面的接口,就会发现有个接口快速进入了限流的返回:

WarmUp预热模式


刚开始QPS为1,10秒后上升为3,再次访问上面接口,可以发现一秒只能访问一次,10秒后会发现访问数有明显提升:

四、熔断策略

新建测试接口:

@RestController
@RequestMapping("/circuitBreaker")
public class CircuitBreakerController 

    @SentinelResource(value = "errdegrade",
            blockHandler = "blockHandler",
            fallback = "fallback")
    @GetMapping("/errdegrade")
    public ResponseTemplate errdegrade()
        System.out.println("请求了!");
        int a = 1 / 0;
        return ResSuccessTemplate.builder().build();
    

    @SentinelResource(value = "timegrade",
            blockHandler = "blockHandler",
            fallback = "fallback")
    @GetMapping("/timegrade")
    public ResponseTemplate timegrade() throws InterruptedException 
        System.out.println("请求了!");
        TimeUnit.SECONDS.sleep(3);
        return ResSuccessTemplate.builder().build();
    

    public ResponseTemplate blockHandler(BlockException exception)
        return ResFailTemplate.builder().code(406).message("接口限流!").build();
    

    public ResponseTemplate fallback()
        return ResFailTemplate.builder().code(400).message("降级处理!").build();
    

慢调用比例

十秒的窗口中,请求数达到4次,有50%的接口时间超过了2秒,即进入熔断,熔断时长5秒后释放一个请求进探测接口是否恢复。

使用测试程序进行测试:

@Slf4j
public class TestDegrade 
    public static void main(String[] args) throws InterruptedException 
        RestTemplate restTemplate = new RestTemplate();

        String url = "http://localhost:8080/circuitBreaker/timegrade";
        for (int i = 1; i <= 20; i++) 
            long t = System.currentTimeMillis();
            String forObject = restTemplate.getForObject(url, String.class);
            log.info("请求次数: , 返回结果: , 耗时:", i, forObject, (System.currentTimeMillis() - t));
        
    


可以看到这些请求都被熔断了。

异常比例


5秒的窗口时间,请求数达到4次,并且50%的都失败,即进入熔断。
修改测试程序:

@Slf4j
public class TestDegrade 
    public static void main(String[] args) throws InterruptedException 
        RestTemplate restTemplate = new RestTemplate();

        String url = "http://localhost:8080/circuitBreaker/errdegrade";
        for (int i = 1; i <= 20; i++) 
            long t = System.currentTimeMillis();
            String forObject = restTemplate.getForObject(url, String.class);
            log.info("请求次数: , 返回结果: , 耗时:", i, forObject, (System.currentTimeMillis() - t));
        
    



共有4个请求进入了,其余均被熔断。

异常数


5秒的窗口时间,请求数达到4次,并且超过2次的失败,即进入熔断。

再次执行测试程序:


其余还是被熔断了。

热点规则


五、Sentinel配制的持久化

上面测试的过程中应该可以发现,服务以重启所有的配制都不见了,这是配制都存在了内存中了,并没有持久化,对于Sentinel可以将配制持久化到nacos中:

添加pom依赖:

<dependency>
   <groupId>com.alibaba.csp</groupId>
   <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

修改配制文件:

spring:
  application:
    name: cloudalibaba-sentinel
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.40.130:8848
    sentinel:
      transport:
        port: 8719 #跟 sentinel 控制台交流的端口,随意指定一个未使用的端口即可默认是8719
        dashboard: 127.0.0.1:8180 # 指定 sentinel 控制台地址。
      eager: true #当服务启动时是否与sentinel建立链接
      web-context-unify: false #关闭 URL PATH 聚合
      datasource:
        ds1:
          nacos:
            server-addr: 192.168.40.130:8848
            dataId: sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

在Nacos中添加配制,data id 为 sentinel-service

配制内容:

[
 
 "resource": "mylimit",
 "controlBehavior": 0,
 "count": 1.0,
 "grade": 1,
 "limitApp": "default",
 "strategy": 0
 
]

重启服务,再次查看Sentinel控制台:

已经被持久化了。

喜欢的小伙伴可以关注我的个人微信公众号,获取更多学习资料!

以上是关于SpringCloud Alibaba Sentinel 服务限流熔断降级 - 基于dashboard方式配制的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud整合Alibaba环境搭建

SpringCloud整合Alibaba环境搭建

SpringCloud整合Alibaba环境搭建

SpringCloud整合Alibaba环境搭建

SpringCloud Alibaba组件

SpringCloud Alibaba Sentinel实现熔断与限流