Sentinel

1.概念

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

  • 丰富的应用场景: Sentinel承接了阿里巴巴近10年的双十-大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可
    以承受的范围)、消息削峰填谷、 集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控: Sentinel同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至500台以下
    规模的集群的汇总运行情况。
  • 广泛的开源生态: Sentinel提供开箱即用的与其它开源框架/库的整合模块,例如与Spring Cloud. Dubbo、 gRPC的整合。您
    只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel.
  • 完善的SPI扩展点: Sentinel提供简单易用、完善的SPI扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规
    则管理、适配动态数据源等。
    Sentinel 目前已经针对Senvlet、Dubbg、 Spring Boot/Spring Cloud. gRPC 等进行了适配,用户只需引入相应依赖并进行简单配
    置即可非常方便地享受Sentinel的高可用流量防护能力。Sentinel 还为Service Mesh提供了集群流量防护的能力。未来Sentinel还
    会对更多常用框架进行适配。
    Sentinel分为两个部分:
  • 核心库(Java客户端)不依赖任何框架/库,能够运行于所有Java运行时环境,同时对Dubbo / Spring Cloud等框架也有较好
    的支持。
  • 控制台(Dashboard) 基于Spring Boot开发,打包后可以直接运行,不需要额外的Tomcat等应用容器。

2.对比

3.控制台

  • 官网下载jar包
  • cmd启动
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar

4.客户端接入控制台

控制台启动后,客户端需要按照以下步骤接入到控制台:

  • 添加依赖
  • 定义资源
  • 建义规则
    先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。

4.1 添加依赖

  • 父工程pom.xml
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  <version>2.1.0.RELEASE</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>
  • 子工程pom.xml
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  • application.yml
spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080
  • 初始化客户端
    确保客户端有访问量,Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包。
    简单的理解就是:访问一次客户端,Sentinel 即可完成客户端初始化操作,并持续向控制台发送心跳包。

4.2 定义资源

资源是Sentinel中的核心概念之一。我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。最常用的资源是我们代码中的Java方法。
Sentinel 提供了@SentinelResource 注解用于定义资源,并提供了AspectJ的扩展用于自动定义资源、处理BlockException 等。
@SentinelResource用于定义资源,并提供可选的异常处理和fallback配置项。@SentinelResource 注解包含以下属性:

  • value :资源名称,必需项(不能为空)
  • entryType : entry 类型,可选项(默认为EntryType .OUT )
  • blockHandler/blockHandlerClass: blockHandler对应处理BlockException的函数名称,可选项。
    blockHandler函数访问范围需要是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException 。
    blockHandler函数默认需要和原方法在同1个类中。若希望使用其他类的函数,则可以指定blockHandlerClass为对应的类的Class 对象,注意对应的函数必需为static函数,否则无法解析。
  • fallback: fllback函数名称,可选项,用于在抛出异常的时候提供fallback处理逻辑。fallback函数可以针对所有类型的异常. (除了exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
    。返回值类型必须与原函数返回值类型一致;
    。方法参数列表需要和原函数一致,或者可以额外多一个Throwable 类型的参数用于接收对应的异常。
    。fallback函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定fallbackClass 为对应的类的Class对象,注意对应的函数必需为static函数,否则无法解析。
  • defaultFallback (since 1.6.0) :默认的fallback函数名称,可选项,通常用于通用的fllback逻辑(即可以用于很多服
    务或方法)。默认fallback函数可以针对所有类型的异常(除了exceptionsToIgnore 里面排除掉的异常类型)进行处
    理。若同时配置了fallback 和defaultFallback,则只有fallback 会生效。defaultFallback 函数签名要求:
    。返回值类型必须与原函数返回值类型-致;
    。方法参数列表需要为空,或者可以额外多- 个Throwable 类型的参数用于接收对应的异常。
    。defaultFallback 函数默认需要和原方法在同-个类中。若希望使用其他类的函数,则可以指定fallbackClass 为对应的类的Class 对象,注意对应的函数必需为static函数,否则无法解析。
  • exceptionsToIgnore (since 1.6.0) :用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入fallback逻辑中,而是会原样抛出。
    注: 1.6.0之前的版本fallback函数只针对降级异常( DegradeException )进行处理,不能针对业务异常进行处理。
  • 基于rest实现的消费者ProductServiceImpl
 @SentinelResource(value = "selectProductById",
         blockHandler = "selectProductByIdBlockHandler", fallback = "FallBack")
    @Override
    public Product selectProductById(Integer id) {
        return restTemplate.getForObject("http://product/product/" + id,
                Product.class);
    }

    //服务流量控制处理
    public Product selectProductByIdBlockHandler(Integer id, BlockException be){
        be.printStackTrace();
        return new Product(id, "BlockHandler", 1, 2666D);
    }

    //服务熔断降级处理
    public Product FallBack(Integer id, Throwable throwable){
        System.out.println("FallBack" + throwable);
        return new Product(id, "FallBack", 1,2666D);
    }

4.3 定义规则

Sentinel的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效。同时Sentinel也提供相关API,供您来定制自
己的规则策略。
Sentinel支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和热点参数规则。

  • 1.管理面板添加流量控制
  • 2.管理面板添加服务降级
  • 3.基于配置文件添加规则
  • application.yml
spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080
        #文件配置规则
      datasource:
        ds1:
          file:
            file: classpath:flowRule.json
            data-type: json
            rule-type: flow
  • 规则文件
[
  {
    "resource": "selectProductList",
    "count": 1,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0
  }
]
  • 4.启动类添加规则
public static void main( String[] args )
{
    SpringApplication.run(ShopSeckill.class);
    initFlowQpsRule();
}

//定义了每秒最多接收2个请求
private static void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule("queryByTimeFromCache");
    // set limit qps to 2
    rule.setCount(2);
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setLimitApp("default");
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

FlowRlue参数
resource:资源名,限流规则的作用对象
limitApp:流控针对的调用来源,若为 default 则不区分调用来源
grade:限流阈值类型,QPS 模式(1)或并发线程数模式(0)
count:限流阈值
strategy:调用关系限流策略:直接、链路、关联
controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)
clusterMode:是否集群限流

5.RestTemplate支持

Spring Cloud Alibaba Sentinel 支持对RestTemplate调用的服务进行服务保护。需要在构造RestTemplate Bean时添加
@SentinelRestTemplate注解。

  • 启动类
@Bean
    @LoadBalanced
    @SentinelRestTemplate(blockHandler = "handleExpection", blockHandlerClass = ExceptionUtil.class,
                fallback = "fallback", fallbackClass = ExceptionUtil.class)
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
  • Expetion类
public class ExceptionUtil {

    //服务流量控制
    public static ClientHttpResponse handlerException(HttpRequest request,
                                                      byte[] body,
                                                      ClientHttpRequestExecution execution,
                                                      BlockException e){
        e.printStackTrace();
        return new SentinelClientHttpResponse(JSON.toJSONString(new Product(1,"BlockHandler",1,255D)));
    }

    //服务熔断降级处理
    public static ClientHttpResponse fallback(HttpRequest request,
                                                      byte[] body,
                                                      ClientHttpRequestExecution execution,
                                                      BlockException e){
        e.printStackTrace();
        return new SentinelClientHttpResponse(JSON.toJSONString(new Product(1,"FALLBACK",1,255D)));
    }
}

6.OpenFeign支持

  • application.yml
feign:
  sentinel:
    enabled: true
  • 启动类
@EnableFeignClients
  • FallbackFactory类
public class FallbackFactory implements feign.hystrix.FallbackFactory<ProductService> {

    @Override
    public ProductService create(Throwable throwable) {
        return new ProductService() {
            @Override
            public Product selectProductById(Integer id) {
                return new Product(id,"Fallback",1,55D);
            }
        };
    }
}
  • ProductService类
@FeignClient(value = "product",fallbackFactory = FallbackFactory.class)
public interface ProductService {

    @GetMapping("/product/{id}")
    Product selectProductById(@PathVariable("id") Integer id);
}
posted @ 2023-07-01 15:27  lwx_R  阅读(9)  评论(0编辑  收藏  举报