• 基于Sentinel的服务保护


    通用资源保护

    引入依赖
    需要注意SpringCloud-Alibaba与SpringCloud的版本关系

     父工程引入 alibaba实现的SpringCloud

    <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Greenwich.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <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>
            </dependencies>
        </dependencyManagement>

    子工程中引入 sentinel

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

    ( 3) 配置熔断降级方法

        @SentinelResource(value="orderFindById",blockHandler = "orderBlockHandler",fallback = "orderFallback")
        @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
        public Product findById(@PathVariable Long id) {
            if(id != 1) {
                throw new RuntimeException("错误");
            }
            return restTemplate.getForObject("http://service-product/product/1",Product.class);
        }
    
    
        /**
         * 定义降级逻辑
         *  hystrix和sentinel
         *      熔断执行的降级方法
         *      抛出异常执行的降级方法
         */
        public Product orderBlockHandler(Long id) {
            Product product = new Product();
            product.setProductName("触发熔断的降级方法");
            return product;
        }
    
        public Product orderFallback(Long id) {
            Product product = new Product();
            product.setProductName("抛出异常执行的降级方法");
            return product;
        }

    @SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource注解包含以下属性:

    • value:资源名称,必需项(不能为空)
    • entryType:entry 类型,可选项(默认为 EntryType.OUT
    • blockHandler / blockHandlerClassblockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
    • fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
      • 返回值类型必须与原函数返回值类型一致;
      • 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
      • fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
    • defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
      • 返回值类型必须与原函数返回值类型一致;
      • 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
      • defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
    • exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

    注:1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,不能针对业务异常进行处理。

    特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandlerfallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出(若方法本身未定义 throws BlockException 则会被 JVM 包装一层 UndeclaredThrowableException)。

    进行测试:

     

     

     先执行2,在5秒里面返回都是这个。

    加载本地配置

      cloud:
        sentinel:
          transport:
            dashboard: 192.168.180.137:8887   #sentinel控制台的请求地址
          datasource:
            ds1:
              file:
                file: classpath:flowrule.json
                data-type: json
                rule-type: flow
          eager: true #立即加载
    [
      {
        "resource": "orderFindById",
        "controlBehavior": 0,
        "count": 1,
        "grade": 1,
        "limitApp": "default",
        "strategy": 0
      }
    ]

    Rest实现熔断
    Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造
    RestTemplate bean的时候需要加上 @SentinelRestTemplate 注解。

    @LoadBalanced
        @Bean
        @SentinelRestTemplate(fallbackClass = ExceptionUtils.class,fallback = "handleFallback",
            blockHandler = "handleBlock" ,blockHandlerClass = ExceptionUtils.class
        )
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }

    @SentinelRestTemplate 注解的属性支持限流( blockHandler , blockHandlerClass )和降级
    ( fallback , fallbackClass )的处理。
    其中 blockHandler 或 fallback 属性对应的方法必须是对应 blockHandlerClass 或
    fallbackClass 属性中的静态方法。
    该方法的参数跟返回值跟
    org.springframework.http.client.ClientHttpRequestInterceptor#interceptor 方法一
    致,其中参数多出了一个 BlockException 参数用于获取 Sentinel 捕获的异常。
    比如上述 @SentinelRestTemplate 注解中 ExceptionUtil 的 handleException 属性对应的方法
    声明如下:

    public class ExceptionUtils {
    
        /**
         * 静态方法
         *      返回值: SentinelClientHttpResponse
         *      参数 : request , byte[] , clientRquestExcetion , blockException
         */
        //限流熔断业务逻辑
        public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
            Product product = new Product();
            product.setProductDesc("限流熔断");
            return new SentinelClientHttpResponse(JSON.toJSONString(product));
        }
    
        //异常降级业务逻辑
        public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body,
            ClientHttpRequestExecution execution, BlockException ex) {
            Product product = new Product();
            product.setProductDesc("异常降级");
            return new SentinelClientHttpResponse(JSON.toJSONString(product));
        }
    
    }

    1秒里面都执行几次,就会这样

    Feign实现熔断
    Sentinel 适配了 Feign 组件。如果想使用,除了引入 sentinel -starter 的依赖外还需要 2 个步骤:
    配置文件打开 sentinel 对 feign 的支持: feign.sentinel.enabled=true
    加入 openfeign starter 依赖使 sentinel starter 中的自动化配置类生效:

    (1) 引入依赖

    <!--springcloud整合的openFeign-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            </dependency>

    ( 2) 开启sentinel 支持
    在工程的application.yml中添加sentinel 对 feign 的支持

    feign:
      sentinel:
        enabled: true

    ( 3)配置FeignClient
    和使用Hystrix的方式基本一致,需要配置FeignClient接口以及通过 fallback 指定熔断降级方法

    /**
     * 声明需要调用的微服务名称
     *  @FeignClient
     *      * name : 服务提供者的名称
     *      * fallback : 配置熔断发生降级方法
     *                  实现类
     */
    @FeignClient(name="service-product",fallback = ProductFeignClientCallBack.class)
    public interface ProductFeignClient {
    
        /**
         * 配置需要调用的微服务接口
         */
        @RequestMapping(value="/product/{id}",method = RequestMethod.GET)
        public Product findById(@PathVariable("id") Long id);
    }
    @Component
    public class ProductFeignClientCallBack implements ProductFeignClient {
    
        /**
         * 熔断降级的方法
         */
        public Product findById(Long id) {
            Product product = new Product();
            product.setProductName("feign调用触发熔断降级方法");
            return product;
        }
    }

    Feign 对应的接口中的资源名策略定义:httpmethod:protocol://requesturl。 @FeignClient 注解中的所有属性,Sentinel 都做了兼容。
    ProductFeginClient 接口中方法 findById 对应的资源名为 GET: http://shop-service-product/product/{str}。

  • 相关阅读:
    [网络流24题]餐巾计划问题
    [网络流24题]方格取数问题
    [网络流24题]试题库问题
    [网络流24题]最长递增子序列问题
    [网络流24题]圆桌问题
    [网络流24题]魔术球问题
    51nod1462 树据结构
    51nod1053 最大M子段和 V2
    51nod1026 矩阵中不重复的元素 V2
    BZOJ3832: [Poi2014]Rally
  • 原文地址:https://www.cnblogs.com/dalianpai/p/12286966.html
Copyright © 2020-2023  润新知