spring cloud alibaba sentinel 流控,服务降级,服务熔断组件

一、 sentinel 主要特性

二、sentinel 的下载及安装

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

下载  sentinel-dashboard-1.7.0.jar  前提是  java8环境OK,8080端口未被占用。

启动 sentinel , java  -jar  sentinel-dashboard-1.7.0.jar 

访问 localhost:8080 ,账号密码均为 sentinel。

三 、创建项目

(1)向 pom文件中 添加相关依赖 : 

  <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--    后续做持久化用到    -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--   sentinel     -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

修改  application.yml 配置文件

server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery: #Nacos注册中心地址
        server-addr: localhost:8848
    sentinel:
      transport: #dashboard地址
        dashboard: localhost:8080
        port: 8719  #默认端口,如果被占用则从8719依次+1扫描
      datasource:
        dsl:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data_type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: "*"

编写 controller 

@RestController
@Slf4j
public class FlowLimitController {

    @GetMapping("/testA")
    public String testA(){
        try {
            TimeUnit.MILLISECONDS.sleep(800);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "---------testA";
    }

    @GetMapping("/testB")
    public String testB(){
        return "----------testB";
    }

}

 

(2)启动 nacos  ,服务注册到 nacos 中,然后启动 sentinel 8080,最后启动微服务,发现 sentinel 中空空如也,因为 sentinel采用的是 懒加载,当访问过了一次接口之后 才会有监控数据展示到 控制台上。

 四、流控规则

 直接 - 》 快速失败 : 选择 qps 时,当一秒内请求数达到阈值就会直接响应失败,当选择线程数时候,一秒内,超过一个线程访问testA接口时,就会直接响应失败。

关联 -》 快速失败

当请求 关联 资源接口  B流量过大时,接口A直接快速响应失败。

(3)Warm Up

 如下例子: 单机阈值为10,预热时长5s, 一开始 qps 为 10/ 3 = 3,慢慢的过了5s之后 qps 就会变为10.

 

秒杀系统:在开启的瞬间,会有很多流量上来,很有可能把系统打死, 预热方式就是为了保护系统,慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。

均匀排队:

 五、服务降级

 

 六、热点key限流

  @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2", required = false) String p2) {
        return "-------testHotKey";
    }

    public String deal_testHotKey(String p1, String p2,
                             BlockException exception){
        return "----deal_testHotKey,o(╥﹏╥)o";

    }

表示访问testHotKey的资源,带有第一个参数的情况下,并且阈值在1秒内达到了1次就会限流,自动调用 blockHandler 的值对应的方法并返回数据。相当于 将 返回的服务降级信息进行了自定义。

参数例外项: 当进行了如下配置的时候,代表p1 !=5 的情况下,每秒1次就会达到阈值,但是当p1 = 5的情况下,阈值每秒可以达到 200 ,注意热点参数的类型必须是 基本类型或者String

@SentinelResource 处理的是Sentinel 控制台配置的违规情况,由blockHandler 配置的方法进行兜底处理。

RuntimeException 

int age = 10 /0 , java运行时爆出的java运行时异常,@SentinelResource 不会处理,

@SentinelResource 主管配置出错,运行出错该走异常走异常。

七、系统规则 

针对整个系统的 第一道 防线

 八、服务降级处理提取类

package springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.springcloud.entities.CommonResult;
import com.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import springcloud.myhandler.CustomerBlockHandler;

@RestController
public class RateLimitController {

    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource(){
        return new CommonResult(200, "按资源名称限流测试ok", new Payment(2020L, "serial001"));
    }

    public CommonResult handleException(BlockException exception) {
        return new CommonResult(444, exception.getClass().getCanonicalName() + "\t 服务不可用");
    }

    @GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl",blockHandlerClass = CustomerBlockHandler.class,
    blockHandler = "handlerException")
    public CommonResult byUrl(){
        return new CommonResult(200,"按url限流测试OK", new Payment(2020L, "serial001"));
    }

    //CustomerBlockHandler
    @GetMapping("/rateLimit/CustomerBlockHandler")
    @SentinelResource(value = "CustomerBlockHandler",blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handlerException2")
    public CommonResult CustomerBlockHandler(){
        return new CommonResult(200,"按客户自定义限流测试OK", new Payment(2020L, "serial003"));
    }

}
package springcloud.myhandler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.springcloud.entities.CommonResult;
import com.springcloud.entities.Payment;

public class CustomerBlockHandler {

    public static CommonResult handlerException(BlockException exception) {
        return new CommonResult(4444, "按客户自定义,global handlerException", new Payment(2020L, "serial0003"));
    }
    public static CommonResult handlerException2(BlockException exception) {
        return new CommonResult(4444, "按客户自定义2,global handlerException", new Payment(2020L, "serial0003"));
    }
}

使业务和代码 耦合度解耦,避免了代码的膨胀。

九、服务熔断 异常忽略 exceptionsToIgnore

十、熔断框架比较

 十一、sentinel 持久化规则

一旦我们重启应用,sentinel 规则将消失,生产环境需要将配置规则进行持久化。

将限流配置规则持久化进nacos 保存,只要不删除nacos中对 限流的配置规则,就不会消失。

主要需要用到 以下依赖:

修改 pom.xml

<!--    后续做持久化用到    -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

修改 application.yml配置文件

 在 nacos 中添加 规则配置:

配置解析:

  [{

 "resource": "/rateLimit/byUrl",

 "limitApp": "default",

 "grade":1,

"count": 1,

"strategy":0,

"controlBehavior":0,

"clusterMode": false

}] 


resource : 资源名称
limitApp: 来源应用,
grade: 阈值类型,0表示线程数,1表示QPS
count: 单机阈值,
strategy: 流控模式,0表示直接,1表示关联,2表示链路
controlBehavior: 流控效果,0表示快速失败,1表示Warm Up ,2表示排队等待
clusterMode: 是否集群

服务停止之后,发现sentinel 中的 链路配置的限流又消失了,但是不用担心,多次请求一下 在nacos 中配置了限流的 资源名称,此时就会发现链路配置的限流数据又出现了。实现了限流配置的持久化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章