SpringCloud(22)之Sentinel实战应用

news2024/12/24 11:26:19

一、Sentinel核心库

        sentinel主页:主页 · alibaba/Sentinel Wiki · GitHub

1.1 Sentinel介绍 

         随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。

1)Sentinel核心组件

1:核心库(Java 客户端 不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同 时对 Dubbo / Spring Cloud 等框架也有较好的支持。

2:控制台(Dashboard):控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。

2)Sentinel VS Hystrix 

对比内容

Sentinel

Hystrix

隔离策略

信号量隔离

线程池隔离/信号量隔离

熔断降级策略

基于响应时间或失败比率

基于失败比率

实时指标实现

滑动窗口

滑动窗口(基于 RxJava

规则配置

支持多种数据源

支持多种数据源

扩展性

多个扩展点

插件的形式

基于注解的支 持

支持

支持

限流

基于 QPS,支持基于调用关系的限流

不支持

流量整形

支持慢启动、匀速器模式

不支持

系统负载保护

支持

不支持

控制台

开箱即用,可配置规则、查看秒级监控、机器 发现等

不完善

常见框架的适 配

ServletSpring Cloud DubbogRPC 

ServletSpring Cloud

Netflix

3)Sentinel概念 

  • 资源:资源是Sentinel的关键概念,他可以是Java应用程序的任何内容,例如,由应用程序提供的服务,或由应用程序调用其他服务提供的服务,甚至可以是一段代码; 只要通过Sentinel API定义的代码,就是资源,能够被Sentinel保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源来标示资源。
  • 规则:围绕资源的实时状态设定的规则,可以包括流量控制规则,熔断规则以及系统保护规则,所有规则可以动态实时调整。

1.2 Sentinel核心功能

 1.2.1 流量控制

        流量控制在网络传输中是一个常用的概念,他用于调整网络包的发送数据,然而,从系统的稳定性角度考虑,也有非常多的讲究。在任意时刻到来的请求往往是随机不可控的,而系统的处理能力有限,我们需要根据系统的的处理能力对流量进行控制.Sentinel作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:

流量控制设计理念 

流量控制有以下几个角度:

  • 资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
  • 运行指标,例如:QPS、线程池、系统负载等;
  • 控制的效果,例如直接限流、冷启动、排队等;

        Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。

1.2.2 熔断降级

        除了流量控制之外,及时对调用链路中的不稳定因素进行熔断也是Sentinel的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,可能会导致请求堆积,进而导致级联故障。

 

        Sentinel 和 Hystrix 的原则是一致的: 当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。

 1)Sentinel熔断设计理念

        Hystrix通过线程池隔离的方式,来对依赖进行了隔离,这样做的好处就是资源和资源之间 做到了最彻底的隔离。缺点就是增加了线程切换的成本,还要先给各个资源做线程池大小的分配。

        Sentinel对这个问题采取了两种手段:

  • 通过并发线程数进行控制

        和资源池隔离的方法不同,Sentinel通过限制资源并发线程的数量,来减少不稳定资源对其他资源的影响。也不需要预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间过长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源商堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才会开始继续处理请求。

  • 通过响应时间对资源进行降级

        除了对并发线程数进行控制外,Sentinel还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会直接被拒绝,直到过了指定时间的窗口后才恢复。

2)系统自适应保护

        Sentinel同时提供系统维度的自适应能力。防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统奔溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其他机器上,如果这个时候其他的机器也处于一个边缘状态,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。

        针对这个情况,Sentinel提供了对应的保护机制,让系统的入口流量和系统负载达到一个平衡,保证系统在能力范围之内处理最多的请求。

1.3 Sentinel熔断限流

         Sentinel可以简单的分为Sentinel核心库和Dashboard。核心库不依赖Dashboard,但是结合Dashboard可以取得最后的效果。我们先来学习一下Sentinel核心库的使用。后面在学习Dashboard的使用。

        在我们项目中,用户请求通过 hailtaxi-gateway路由到 hailtaxi-driver 或者 hailtaxi-order ,还 有可能在 hailtaxi-order 中使用feign调用 hailtaxi-driver ,所以我们有可能在单个服务中实现熔   断限流,也有可能要集成feign调用实现熔断限流,还有可能在微服务网关中实现熔断限流。我们接下   来一步一步实现每一种熔断限流操作。 

1.3.1 Springboot集成

        如果在Springboot项目中集成,首先需要引入依赖,并使用@SentinelResource标记资源。

 1.3.1.1 @SentinelResource注解

         @SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。

        @SentinelResource 注解包含以下属性:

value

资源名称,必需项(不能为空)

blockHandler /

blockHandlerClass

blockHandler 对应处理 BlockException 的函数名称,可选项。    blockHandler 函数访问范围需要是 public 返回类型需要与原  方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的 参数,类型为 BlockException  blockHandler 函数默认需要和 原方法在同一个类中。若希望使用其他类的函数,则可以指定

blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必 需为 static 函数,否则无法解析。

fallback / fallbackClass

fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback

处理逻辑。fallback 函数可以针对所有类型的异常(除了

exceptionsToIgnore 里面排除掉的异常类型)进行处理。  fallback 函数签名和位置要求:  返回值类型必须与原函数返回值类型一

致; 方法参数列表需要和原函数一致,或者可以额外多一个

Throwable 类型的参数用于接收对应的异常。   fallback 函数默认 需要和原方法在同一个类中。若希望使用其他类的函数,则可以指  fallbackClass 为对应的类的 Class 对象,注意对应的函数必需    static 函数,否则无法解析。

defaultFallback(1.6.0  )

默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑 (即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类   型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处 理。若同时配置了 fallback defaultFallback,则只有 fallback     会生效。  defaultFallback 函数签名要求:  返回值类型必须与原   函数返回值类型一致; 方法参数列表需要为空,或者可以额外多 一个 Throwable 类型的参数用于接收对应的异常。   

defaultFallback 函数默认需要和原方法在同一个类中。若希望使用 其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 

象,注意对应的函数必需为 static 函数,否则无法解析。

exceptionsToIgnore(1.6.0 开始)

用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

entryType

entry 类型,可选项(默认为 EntryType.OUT)

1.3.1.2 blockHandler

        在对应的模块中加入依赖:

        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        我们为 info()方法添加一个 @SentinelResource注解,用来标注资源,表示当前方法需要执行限流、降级,在注解中添加value属性,用来标注资源,说白了就是给当前资源起个名字,blockHandler  用来表示当前方法发生 BlockException异常的时候,将处理流程交给指定的方法 blockExHandler() 处理,此时 blockExHandler()方法必须和抛出异常的方法在同一个类中,这是一种降级操作,代码如   下:

    @SentinelResource(value = "info",blockHandler = "blockExHandler")
    public Driver info(@PathVariable(value = "id")String id) throws InterruptedException{
        Driver driver = driverService.findById(id);
        //if(id.equals("1")){
        //    TimeUnit.SECONDS.sleep(10);
        //}
        if(driver==null){
            //throw new RuntimeException("司机不存在");
            throw new SystemBlockException("info","hailtaxi-driver");//必须抛出BlockException才会生效
        }
        driver.setName(driver.getName()+",IP="+ip);
        return driver;
    }

    /***
     * BlockException异常处理
     */
    public Driver blockExHandler(String id,BlockException ex){
        Driver driver = new Driver();
        driver.setId(id);
        driver.setName("bbb");
        return driver;
    }

        如果访问一个没有的数据就会报错异常,此时就会走blockhandler里面的逻辑。

1.3.1.3 fallback使用 

         如果我们希望抛出任何异常都能处理,都能调用默认处理方法,而并非只是 BlockException异常才调 用,此时可以使用 @SentinelResource  fallback属性,代码如下:

    @SentinelResource(value = "info",fallback ="exHandler")
    public Driver info(@PathVariable(value = "id")String id) throws InterruptedException{
        Driver driver = driverService.findById(id);
        //if(id.equals("1")){
        //    TimeUnit.SECONDS.sleep(10);
        //}
        if(driver==null){
            throw new RuntimeException("司机不存在");
//            throw new SystemBlockException("info","hailtaxi-driver");//必须抛出BlockException才会生效
        }
        driver.setName(driver.getName()+",IP="+ip);
        return driver;
    }

    /***
     * 异常处理
     */
    public Driver exHandler(String id){
        Driver driver = new Driver();
        driver.setId(id);
        driver.setName("aaa");
        return driver;
    }

         访问 http://localhost:18081/driver/info/3 测试出错效果如下:

        如果我们处理异常逻辑跟原方法不在同一个类中,可以使用@SentinelResource注解的fallbackclass实现,代码如下:

@SentinelResource(value = "info",fallback ="exHandler" ,fallbackClass ="xx.xxx.xxx.xx.Xxx")
 1.3.1.4 defaultFallback

         上面无论是 blockHandler还是 fallback ,每个方法发生异常,都要为方法独立创建一个处理异常的   方法,效率非常低,我们可以使用 @SentinelResource注解的 defaultFallback属性,为一个类指定 一个全局的处理错误的方法,代码如下:

@RestController
@RequestMapping(value = "/driver")
@RefreshScope
@SentinelResource(defaultFallback ="defaultExFallback")
public class DriverController {

    /***
     * 异常处理
     */
    public Driver defaultExFallback() {
        Driver driver = new Driver();
        driver.setName("系统繁忙,请稍后再试!");
        return driver;
    }
}

         此时需要注意,  defaultFallback属性指定的方法入参必须为空,最多可以增加一个异常对象。我们访问 http://localhost:18081/driver/info/3 效果如下:

1.3.2 限流规则 

         Sentinel支持多种限流规则,规则我们可以在代码中直接定义,规则属性如下:

Field

说明

默认值

resource

资源名,资源名是限流规则的作用对象

count

限流阈值

grade

限流阈值类型,QPS 模式(1)或并发线程数模式  0

QPS 模式

limitApp

流控针对的调用来源

default ,代表不区 分调用来源

strategy

调用关系限流策略:直接、链路、关联

根据资源本身(直

接)

controlBehavior

流控效果(直接拒绝/WarmUp/匀速+排队等 ),不支持按调用关系限流

直接拒绝

clusterMode

是否集群限流

1.3.2.1 流量控制 

         理解上面规则的定义之后,我们可以通过调用  FlowRuleManager.loadRules() 方法来用硬编码的方 式定义流量控制规则。

1)QPS流量控制

         我们先实现流量基于QPS控制,在 hailtaxi-driver  DriverApplication启动类上添加如下方法加 载限流规则,当 DriverApplication初始化完成之后加载规则,代码如下:

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan(basePackages = "com.xxxxx.driver.mapper")
@EnableAutoDataSourceProxy
public class DriverApplication {

    public static void main(String[] args) throws InterruptedException {
        ApplicationContext applicationContext = SpringApplication.run(DriverApplication.class,args);
    }

    /***
     * 初始化规则
     */
    @PostConstruct
    private void initFlowQpsRule() {
        //规则集合
        List<FlowRule> rules = new ArrayList<FlowRule>();
        //定义一个规则
        FlowRule rule = new FlowRule("info");
        // 设置阈值
        rule.setCount(2);
        //设置限流阈值类型
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);//QPS控制
//        rule.setGrade(RuleConstant.FLOW_GRADE_THREAD);//线程数控制
        //default,代表不区分调用来源
        rule.setLimitApp("default");
        //将定义的规则添加到集合中
        rules.add(rule);
        //加载规则
        FlowRuleManager.loadRules(rules);
    }
}

        我们访问 http://localhost:18081/driver/info/1此时不会抛出异常,但是频繁刷新,则会调用降 级方法,效果如下: 

2)线程数流量控制 

         我们修改限流阈值类型,代码如下:

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan(basePackages = "com.xxxxx.driver.mapper")
@EnableAutoDataSourceProxy
public class DriverApplication {

    public static void main(String[] args) throws InterruptedException {
        ApplicationContext applicationContext = SpringApplication.run(DriverApplication.class,args);
    }

    /***
     * 初始化规则
     */
    @PostConstruct
    private void initFlowQpsRule() {
        //规则集合
        List<FlowRule> rules = new ArrayList<FlowRule>();
        //定义一个规则
        FlowRule rule = new FlowRule("info");
        // 设置阈值
        rule.setCount(2);
        //设置限流阈值类型
        rule.setGrade(RuleConstant.FLOW_GRADE_THREAD);//线程数控制
        //default,代表不区分调用来源
        rule.setLimitApp("default");
        //将定义的规则添加到集合中
        rules.add(rule);
        //加载规则
        FlowRuleManager.loadRules(rules);
    }
}

         此时再来访问 http://localhost:18081/driver/info/1我们发现用浏览器无论怎么访问都不会出现 降级现象,但是如果用Jmeter模拟多个线程,效果就不一样了,效果如下:

 1.3.2.2 熔断降级

         熔断降级规则包含下面几个重要的属性:

Field

说明

默认

resource

资源名,即规则的作用对象

grade

熔断策略,支持慢调用比例/异常比例/异常数策略

慢调

用比

count

慢调用比例模式下为慢调用临界 RT(超出该值计为慢调 );异常比例/异常数模式下为对应的阈值

timeWindow

熔断时长,单位为 s

minRequestAmount

熔断触发的最小请求数,请求数小于该值时即使异常比率超出 阈值也不会熔断(1.7.0 引入)

5

statIntervalMs

统计时长(单位为 ms ), 60*1000 代表分钟级(1.8.0  入)

1000

ms

slowRatioThreshold

慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

         同一个资源可以同时有多个降级规则。理解上面规则的定义之后,我们可以通过调用 DegradeRuleManager.loadRules() 方法来用硬编码的方式定义流量控制规则,在  DriverApplication 规则定义如下:

    /***
     * 熔断降级规则
     */
    @PostConstruct
    private void initDegradeRule() {
        //降级规则集合
        List<DegradeRule> rules = new ArrayList<DegradeRule>();
        //降级规则对象
        DegradeRule rule = new DegradeRule();
        //设置资源
        rule.setResource("info");
        //设置触发降级阈值
        rule.setCount(2);
        /**
         * 熔断降级策略,支持慢调用比例/异常比例/异常数策略
         * DEGRADE_GRADE_RT:平均响应时间
         * DEGRADE_GRADE_EXCEPTION_RATIO:异常比例数量
         * DEGRADE_GRADE_EXCEPTION_COUNT:异常数
         */
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        //熔断窗口时长,单位为 s
        rule.setTimeWindow(10);
        //将规则添加到集合中
        rules.add(rule);
        //加载规则
        DegradeRuleManager.loadRules(rules);
    }
 1.3.2.3 系统自我保护

         Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 LoadCPU 使用率、总体 平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量 和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

        系统规则包含下面几个重要的属性:

Field

说明

默认值

highestSystemLoad

load1 触发值,用于触发自适应控制阶段

-1 (不生效)

avgRt

所有入口流量的平均响应时间

-1 (不生效)

maxThread

入口流量的最大并发数

-1 (不生效)

qps

所有入口资源的 QPS

-1 (不生效)

highestCpuUsage

当前系统的 CPU 使用率(0.0-1.0

-1 (不生效)

         理解上面规则的定义之后,我们可以通过调用 SystemRuleManager.loadRules() 方法来用硬编码的 方式定义流量控制规则。

    /***
     * 系统自我保护
     */
    //@PostConstruct
    private void initSystemRule() {
        //系统自我保护集合
        List<SystemRule> rules = new ArrayList<>();
        //创建系统自我保护规则
        SystemRule rule = new SystemRule();
        //CPU使用率 值为0-1,-1 (不生效)
        rule.setHighestCpuUsage(0.2);
        //所有入口资源的 QPS,-1 (不生效)
        rule.setQps(10);
        //入口流量的最大并发数,-1 (不生效)
        rule.setMaxThread(5);
        //所有入口流量的平均响应时间,单位:秒,-1 (不生效)
        rule.setAvgRt(5);
        //load1 触发值,用于触发自适应控制阶段,系统最高负载,建议取值 CPU cores * 2.5
        rule.setHighestSystemLoad(20);
        //将规则加入到集合
        rules.add(rule);
        SystemRuleManager.loadRules(rules);
    }
1.3.2.4 热点数据 

         何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K  据,并对其访问进行限制。比如:

1:商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制

2:用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

         热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调 用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效.

         Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点 参数限流支持集群模式。

        要使用热点参数限流功能,需要引入以下依赖:

        <!--热点参数-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-parameter-flow-control</artifactId>
            <version>1.8.1</version>
        </dependency>

        然后为对应的资源配置热点参数限流规则,并在 entry  的时候传入相应的参数,即可使热点参数限流 生效。

         热点参数规则(  ParamFlowRule  )类似于流量控制规则(  FlowRule ):

属性

说明

默认值

resource

资源名,必填

count

限流阈值,必填

grade

限流模式

QPS  

durationInSec

统计窗口时间长度(单位为秒),1.6.0 版本开始支持

1s

controlBehavior

流控效果(支持快速失败和匀速排队模式),1.6.0 版本开 始支持

快速失

maxQueueingTimeMs

最大排队等待时长(仅在匀速排队模式生效),1.6.0 版本 开始支持

0ms

paramIdx

热点参数的索引,必填,对应 SphU.entry(xxx, args) 中的参数索引位置

paramFlowItemList

参数例外项,可以针对指定的参数值单独设置限流阈值, 不受前面 count 阈值的限制。  仅支持基本类型和字符串  类型

         我们可以对热门参数比如下标为0的参数流量进行控制,对热点数据执行特殊限流,比如参数值为 tj  时候执行限流,在 DriverApplication 中创建限流配置,代码如下:

    /***
     * 热点参数初始化
     */
    @PostConstruct
    private static void initParamFlowRules() {
        ParamFlowRule rule = new ParamFlowRule("search")
                //参数下标为0
                .setParamIdx(0)
                //限流模式为QPS
                .setGrade(RuleConstant.FLOW_GRADE_QPS)
                //统计窗口时间长度(单位为秒)
                .setDurationInSec(10)

                /**
                 * 流控效果(支持快速失败和匀速排队模式)
                 * CONTROL_BEHAVIOR_DEFAULT:限流行为,直接拒绝
                 * CONTROL_BEHAVIOR_WARM_UP:限流行为,匀速排队 冷启动
                 * CONTROL_BEHAVIOR_RATE_LIMITER:限流行为,匀速排队
                 */
                .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)
                //最大排队等待时长(仅在匀速排队模式生效  CONTROL_BEHAVIOR_RATE_LIMITER)
                //.setMaxQueueingTimeMs(600)
                //最大阈值为5
                .setCount(5);

        // 为特定参数单独设置阈值.
        //如下配置:当下标为0的参数值为tj的时候,阈值到达2的时候则执行限流
        ParamFlowItem item = new ParamFlowItem()
                //参数类型为int类型
                .setClassType(String.class.getName())
                //设置阈值为2
                .setCount(2)
                //需要统计的值
                .setObject(String.valueOf("tj"));
        rule.setParamFlowItemList(Collections.singletonList(item));
        //加载热点数据
        ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
    }

1.3  Sentinel对OpenFeign支持 

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

1:配置文件打开 Sentinel  Feign 的支持:feign.sentinel.enabled=true

2:加入 spring-cloud-starter-openfeign 依赖使 Sentinel starter 中的自动化配置类生效

1)引入依赖 

        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.5.RELEASE</version>
        </dependency>

        <!--Openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

 2)还需要在Feign调用客户端中开启Feign的支持

feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
      min-request-size: 2048 # 设置触发压缩的大小下限
      #以上数据类型,压缩大小下限均为默认值
    response:
      enabled: true # 开启响应压缩
  #开启Sentinel对Feign的支持
  sentinel:
    enabled: true

 1.3.1 fallback

         我们可以为Feign接口创建一个实现类,在实现类中处理程序异常降级处理方法,代码如下:

@Component
public class DriverFeignFallback implements DriverFeign {

    /**
     * status()降级处理方法
     */
    @Override
    public Driver status(String id, Integer status) {
        Driver driver = new Driver();
        driver.setId(id);
        driver.setStatus(status);
        driver.setName("系统比较繁忙,请您稍后再试!");
        return driver;
    }
}

         我们还需要在Feign接口上添加 fallback属性指定讲解处理的类,代码如下:

@FeignClient(value = "hailtaxi-driver",fallback = DriverFeignFallback.class)

1.3.2 fallbackFactory 

        我们可以为Feign接口创建一个降级处理的工厂对象,在工厂对象中处理程序异常降级处理方法,代码 如下:

@Component
public class DriverFeignFallbackFactory implements FallbackFactory<DriverFeign> {

    @Override
    public DriverFeign create(Throwable throwable) {
        return new DriverFeign() {

            /**
             * status()降级处理方法
             */
            @Override
            public Driver status(String id, Integer status) {
                Driver driver = new Driver();
                driver.setId(id);
                driver.setStatus(status);
                driver.setName("系统比较繁忙,请您稍后再试!");
                return driver;
            }
        };
    }
}

         我们还需要在Feign接口上添加 fallbackFactory属性指定讲解处理的类,代码如下:

@FeignClient(value = "hailtaxi-driver",fallbackFactory =
DriverFeignFallbackFactory.class)

         此时我们测试,效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1517504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

有趣的前端知识(三)

推荐阅读 有趣的前端知识&#xff08;一&#xff09; 有趣的前端知识&#xff08;二&#xff09; 文章目录 推荐阅读JS内置对象JS外部对象BOM模型history对象screen对象navigator对象 DOM&#xff08;文档对象模型&#xff09;DOM的方法&#xff08;对于节点的操作&#xff09…

Rudolf and the Ball Game

传送门 题意 思路 暴力枚举每一个妆台的转换条件 code #include<iostream> #include<cstdio> #include<stack> #include<vector> #include<algorithm> #include<cmath> #include<queue> #include<cstring> #include<ma…

ChatGPT 插件Plugin集合

ChatGPT的插件功能推出一段时间了&#xff0c;陆陆续续的上架了得有200了。 但是其中大部分都不是很好用&#xff0c;并且找起来也复杂。 推荐一个不知名热心人做的导航页。 ChatGPT Plugins Overview 基本上集合了所有的插件&#xff0c;并且还在实时更新中。 需要升级4.0&a…

el-input设置max、min无效的解决方案

目录 一、方式1&#xff1a;type“number” 二、方式2&#xff1a;oninput&#xff08;推荐&#xff09; 三、计算属性 如下表所示&#xff0c;下面为官方关于max&#xff0c;min的介绍&#xff1a; el-input&#xff1a; max原生属性&#xff0c;设置最大值min原生属性&a…

<Senior High School Math>: inequality question

( 1 ) . o m i t (1). omit (1).omit ( 2 ) . ( a 2 − b 2 ) ( x 2 a 2 − y 2 b 2 ) ( x 2 y 2 ) − ( a 2 y 2 b 2 b 2 x 2 a 2 ) ≤ x 2 y 2 − 2 x y ( x − y ) 2 (2). (a^2-b^2)(\frac{x^2}{a^2} - \frac{y^2}{b^2})(x^2y^2)-(\frac{a^2y^2}{b^2}\frac{b^2x^2}{a^…

自然语言处理NLP:tf-idf原理、参数及实战

大家好&#xff0c;tf-idf作为文体特征提取的常用统计方法之一&#xff0c;适合用于文本分类任务&#xff0c;本文将从原理、参数详解和实际处理方面介绍tf-idf&#xff0c;助力tf-idf用于文本数据分类。 1.tf-idf原理 tf 表示词频&#xff0c;即某单词在某文本中的出现次数与…

【刷题】双指针进阶

请看入门篇 &#xff1a;双指针入门 送给我们一句话&#xff1a; 如今我努力奔跑&#xff0c;不过是为了追上那个曾经被寄予厚望的自己 —— 约翰。利文斯顿 双指针进阶 Leetcode 611 有效三角形的个数Leetcode LCR179.查找总价格为目标值的两个商品Leetcode 15.三数之和Thanks…

uniapp中人脸识别图片并圈起人脸

效果如上&#xff0c;我用的是阿里云的人脸识别。首先&#xff0c;我们先封装一个阿里云的请求js文件 faceRecognition.js import CryptoJS from crypto-js//SignatureNonce随机数字 function signNRandom() {const Rand Math.random()const mineId Math.round(Rand * 1000…

UE5 android打包

下载安装JDK https://repo.huaweicloud.com/java/jdk/https://repo.huaweicloud.com/java/jdk/ 选择对应的jdk版本 配置环境变量 编辑Path 验证是否成功 java -version 安装Android Studio https://developer.android.google.cn/studio?hlzh-cnhttps://developer.androi…

EMQX 4.0和EMQX 5.0集群架构实现1亿MQTT连接哪些改进

EMQX 5.0水平扩展能力得到了指数级提升&#xff0c;能够更可靠地承载更大规模的物联网设备连接量。 在EMQX5.0正式发布前的性能测试中&#xff0c;我们通过一个23节点的EMQX集群&#xff0c;全球首个达成了1亿MQTT连接每秒100万消息吞吐&#xff0c;这也使得EMQX 5.0成为目前为…

【C++ 设计模式】简单工厂模式

文章目录 前言一、简单工厂模式是什么&#xff1f;二、实现原理三、UML类图四、简单工厂模式具体代码总结 前言 在软件开发中&#xff0c;设计模式是解决特定问题的可复用解决方案。其中&#xff0c;简单工厂模式是一种创建型设计模式&#xff0c;旨在封装对象的创建过程&…

IDEA开启Run Dashboard

1、Run Dashboard是什么&#xff0c;为什么要使用 Run Dashboard 是 IntelliJ IDEA 中的一个工具窗口&#xff0c;用于管理和监视项目中正在运行的应用程序和配置。它提供了一种集中管理运行和调试过程的方式&#xff0c;可以让开发人员更方便地查看和控制正在运行的应用程序。…

2 Redis的安装与配置

这里是要将 Redis 安装到 Linux 系统中。 1.1 Redis 的安装 1.1.1 克隆并配置主机 修改主机名&#xff1a;/etc/hostname修改网络配置&#xff1a;/etc/sysconfig/network-scripts/ifcfg-ens33 1.1.2 安装前的准备工作 &#xff08;1 &#xff09;安装 gcc &#xff08;2…

如何从 Mac 电脑外部硬盘恢复删除的数据文件

本文向您介绍一些恢复 Mac 外置硬盘数据的快速简便的方法。 Mac 的内部存储空间通常不足以存储所有数据。因此&#xff0c;许多用户通过外部驱动器扩展存储或创建数据备份。然而&#xff0c;与几乎所有其他设备一样&#xff0c;从外部硬盘驱动器丢失有价值的数据并不罕见。由于…

数据库是什么?数据库连接、管理与分析工具推荐

一、数据库是什么&#xff1f; 数据库是一种结构化的数据存储系统&#xff0c;用于有效地组织、存储和管理大量的数据。它是一个集中化的数据存储库&#xff0c;通常由一个或多个数据表组成&#xff0c;每个数据表包含多个行和列&#xff0c;用于存储特定类型的数据。数据表中…

SQLiteC/C++接口详细介绍之sqlite3类(七)

上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;六&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍之sqlite3类&#xff08;八&#xff09;&#xff08;未发表&#xff09; 22.sqlite3_create_collation、sqlite3_create_collation16和sqlite3_creat…

【java工具】Maven的下载配置+setting配置(以3.9.6为例)

本人正在学习spring&#xff0c;还是个小白&#xff0c;也是跟着网课和各种资料学&#xff0c;光学习spring项目的各种配置就花了我不少时间QWQ。在学习spring的每个阶段&#xff0c;我会做好技术总结&#xff0c;不定期分享出来&#xff0c;希望对你有所帮助&#xff0c;有问题…

【Node.js从基础到高级运用】十二、身份验证与授权:JWT

身份验证与授权是现代Web应用中不可或缺的部分。了解如何在Node.js应用中实施这些机制&#xff0c;将使你能够构建更安全、更可靠的应用程序。本文将引导你通过使用JWT实现用户注册、登录和权限控制的过程。 JWT&#xff08;Json Web Token&#xff09; JWT是一种用于双方之间…

COX回归影响因素分析的基本过程与方法

在科学研究中&#xff0c;经常遇到分类的结局&#xff0c;主要是二分类结局&#xff08;阴性/阳性&#xff1b;生存/死亡&#xff09;&#xff0c;研究者可以通过logistic回归来探讨影响结局的因素&#xff0c;但很多时候logistic回归方法无法使用。如比较两种手段治疗新冠肺炎…

报表生成器FastReport .Net用户指南:关于脚本(上)

FastReport的报表生成器&#xff08;无论VCL平台还是.NET平台&#xff09;&#xff0c;跨平台的多语言脚本引擎FastScript&#xff0c;桌面OLAP FastCube&#xff0c;如今都被世界各地的开发者所认可&#xff0c;这些名字被等价于“速度”、“可靠”和“品质”,在美国&#xff…