zoukankan      html  css  js  c++  java
  • 客户端容错保护Alibaba Sentinel

    18年底Netflix官方宣布Hystrix 已经足够稳定,不再积极开发 Hystrix,该项目将处于维护模式。就目前来看Hystrix是比较稳定的,并且Hystrix只是停止开发新的版本,并不是完全停止维护,Bug什么的依然会维护的。因此短期内,Hystrix依然是继续使用的。但从长远来看,Hystrix总会达到它的生命周期的。

    Hystrix的替换方案:Alibaba Sentinel、Resilience4J

      

    Sentinel概述:

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

      Sentinel 具有以下特征:
        丰富的应用场景 :Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
        完备的实时监控 :Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
        广泛的开源生态 :Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 SpringCloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
        完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

      Sentinel 的主要特性:

        

      Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard。核心库不依赖 Dashboard,但是结合Dashboard 可以取得最好的效果。

      使用 Sentinel 来进行熔断保护,主要分为几个步骤:

        1. 定义资源
        2. 定义规则
        3. 检验规则是否生效

        资源:可以是任何东西,一个服务,服务里的方法,甚至是一段代码。
        规则:Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则和热点参数规则。
             Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效
        先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。

    Sentinel组件:

      管理控制台:
        获取 Sentinel 控制台 https://github.com/alibaba/Sentinel

        在存放jar包的目录,使用如下命令启动控制台:

          java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-x.x.x.jar
          其中 - Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080 。

          在浏览器中访问 http://localhost:8080/ 输入账号密码即可登录

          从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel

          启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。

        在使用 Sentinel 控制台设置微服务各种访问规则是存在内存中的,在微服务重启后规则就会丢失,需要持久化保存

          

           https://www.jianshu.com/p/609961eb6a6e

      将所有的服务交给控制台管理:

        客户端接入控制台:

          在客户端(需要管理的微服务)引入坐标

            客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信。可以通过 pom.xml 引入 JAR 包:

    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-transport-simple-http</artifactId>
    </dependency>

          在客户端配置启动参数

    spring:
      #配置控制台的请求路径。
      cloud:
        sentinel:
          transport:
            dashboard: localhost:8080

        查看机器列表以及健康情况:访问 http://localhost:8080/ 可看到刚才接入的客户端

          

          默认情况下 Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包。也可以配置sentinel.eager=true ,取消Sentinel控制台懒加载。

    基于Sentinel的服务保护:

      通用资源保护:

        1.引入依赖

          需要注意SpringCloud-Alibaba与SpringCloud的版本关系

          

           父工程引入 alibaba实现的SpringCloud

    <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>

          子工程(服务消费者)中引入 sentinel

    <!-- 当引入此依赖时,前面的客户端(对应此子工程)的sentinel-transport-simple-http就可以省略了,因为此依赖已包含了它 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>

        2.配置熔断降级方法

    /**
     * 订单控制层
     */
    @RestController
    @RequestMapping("/order")
    public class OrderController {
        @Autowired
        private RestTemplate restTemplate;
    
        /**
         * 通过订单系统,调用商品服务根据id查询商品信息
         * @param id
         * @return
         */
        @GetMapping("/buy/{id}")
        @SentinelResource(value="order",blockHandler = "orderBlockHandler",fallback = "orderFallback")
        public Product findById(@PathVariable("id") Long id) {
            return restTemplate.getForObject("http://service-product/product/" + id, Product.class);
        }
    
        // 熔断降级方法
        public Product orderBlockHandler(Long id) {
            Product product = new Product();
            product.setId(-2l);
            product.setProductName("触发熔断降级方法");
            return product;
        }
        // 抛出异常降级方法
        public Product orderFallback(Long id) {
            Product product = new Product();
            product.setId(-1l);
            product.setProductName("触发抛出异常降级方法");
            return product;
        }
    }

          在需要被保护的方法上使用 @SentinelResource 注解进行熔断配置。与Hystrix不同的是,Sentinel对抛出异常和熔断降级做了更加细致的区分,通过 blockHandler 指定熔断降级方法,通过 fallback 指定触发异常执行的降级方法。
          对于@SentinelResource的其他配置如下表:

          

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

          特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。
          若未配置 blockHandler 、 fallback 和 defaultFallback ,则被限流降级时会将 BlockException 直接抛出。

      Feign实现熔断:

        Sentinel 适配了 Feign 组件。如果想使用,除了引入 sentinel -starter 的依赖外还需要 2 个步骤:

          配置文件打开 sentinel 对 feign 的支持: feign.sentinel.enabled=true
          加入 openfeign starter 依赖使 sentinel starter 中的自动化配置类生效

        1.引入依赖

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

        2.开启sentinel 支持

    #配置feign
    feign:
      sentinel:
        enabled: true

        3.配置FeignClient

          编写FeignClient接口的实现类

          基于Feign实现熔断降级,需要实现自定义的ProductFeginClient接口,且实现类需要扫描到容器中(@Component),降级方法就是实现接口的方法

    @Component
    public class ProductFeignClientImpl implements ProductFeignClient {
    
        /**
         * 熔断降级的方法
         * @param id
         * @return
         */
        @Override
        public Product findById(Long id) {
            Product product = new Product();
            product.setId(-1L);
            product.setProductName("熔断,触发降级方法");
            return product;
        }
    }

          修改FeignClient添加hystrix熔断

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

        Feign 对应的接口中的资源名策略定义:httpmethod:protocol://requesturl。 @FeignClient 注解中的所有属性,Sentinel 都做了兼容。

          ProductFeginClient 接口中方法 findById 对应的资源名为 GET:http://service-product/product/{id},根据注册中心最终转成需要调用的微服务的地址
        4.启动测试

          .........

        

         

          注意:此工厂类必须放置在其实现接口的同级包或子包下

  • 相关阅读:
    通过一个程序来理解PHP里面的抽象类【1】
    mycheckpoint 把玩手记
    Mysql 大量 unauthenticated user
    零基础学习Oracle 10G视频教程
    mysql show processlist命令 详解
    c# 中的事件
    c# 中方法签名 指的是?
    c# 中的索引
    介绍如何使用C#中的委托
    C# 语法学习笔记
  • 原文地址:https://www.cnblogs.com/roadlandscape/p/12501576.html
Copyright © 2011-2022 走看看