SpringBoot实战(十六) 集成Hystrix

news2024/11/14 1:30:08

目录

    • 一、简介
      • 1.Hystrix 的定义?
      • 2.Hystrix 的用处?
      • 3.Hystrix 的三种状态?
      • 4.Hystrix 解决什么问题?
      • 5.Hystrix 的设计原理?
      • 6.Hystrix 的实现原理?
    • 二、集成 Hystrix
      • 1.Maven 依赖
      • 2.application.yml
        • 简易版:
        • 完整版:
      • 3.添加@EnableHystrix注解
      • 4.HystrixConfig.java 配置类
      • 5.HystrixTestController.java 测试类
        • 5.1)实现代码
        • 5.2)执行结果
        • 5.3)总结
      • 6.补充:@HystrixProperty 的常见用法
    • 三、Feign中Hystrix的使用
      • 1.配置文件
      • 2.HystrixTestFeignClient.java Feign调用
      • 3.HystrixTestFeignClientFallBack.java 熔断类
      • 4.HystrixFeignTestController.java 测试类
        • 4.1)实现代码
        • 4.2)执行结果
        • 4.3)总结

在这里插入图片描述

一、简介

注意:Hystrix 已经停止开发新版本了,仅在进行部分维护工作,最后一版为2018年11月发布。

1.Hystrix 的定义?

Hystrix: 是由 Netflix 开源的一个服务隔离组件。在分布式环境中,服务与服务之间的依赖错综复杂,一种不可避免的情况就是总会有某些服务会出现故障,导致依赖于它们的其它服务出现远程调度的线程阻塞。Hystrix 提供了 熔断器 功能,能够阻止分布式系统中出现联动故障。Hystrix 是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从而提高了整个分布式系统的弹性。

官方文档: https://github.com/Netflix/Hystrix/wiki/

GitHub: https://github.com/Netflix/Hystrix

2.Hystrix 的用处?

  • 通过第三方客户端访问(通常是通过网络)依赖服务来保护并控制延迟和故障。
  • 停止复杂分布式系统中的级联故障。
  • 快速失败并快速恢复。
  • 尽可能回退并优雅地降级。
  • 实现近乎实时的监控、告警和操作控制。

3.Hystrix 的三种状态?

1)熔断关闭状态(Closed)

服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制。

2)熔断开启状态(Open)

在固定时间窗口内(Hystrix 默认是 10 秒),接口调用出错比率达到一个阈值(Hystrix 默认为 50%),会进入熔断开启状态。进入熔断状态后,后续对该服务接口的调用不再经过网络,直接执行本地的 fallback() 方法。

3)半熔断状态(Half-Open)

在进入熔断开启状态一段时间后(Hystrix 默认是 5 秒),熔断器会进入半熔断状态。所谓半熔断就是尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断关闭状态。

三个状态的转化关系如下图所示:

在这里插入图片描述

4.Hystrix 解决什么问题?

当一切正常时,请求流程可能如下所示:

在这里插入图片描述

当许多后端系统之一有了潜在变慢的危险时,它就可以阻止整个用户请求:

在这里插入图片描述

在高流量的情况下,单个后端依赖服务上如果出现潜在变慢的危险可能会导致所有服务器上的所有资源在几秒钟内变得饱和。

通过网络请求和被请求的应用程序中,每个点的潜在故障都是可能导致网络请求服务变慢的故障来源。比故障更糟糕的是,这些应用还可能导致服务之间的延迟增加,这会备份列表、线程和其他系统资源,从而导致整个系统发生更多的级联故障。

在这里插入图片描述

当通过第三方客户端执行网络请求时,这些问题会加剧从而变成一个“黑匣子”,其中的实现细节被隐藏,并且每个客户端的网络或资源配置都不相同,通常难以监控和控制。

5.Hystrix 的设计原理?

  • 防止单个依赖项耗尽所有容器(例如 Tomcat)用户线程。
  • 快速卸载负载,让请求失败而不是排队。
  • 在可行的情况下提供回退以保护用户后续请求正常。
  • 使用隔离技术(例如 bulkhead(隔板),swimlane(泳道),circuit breaker(断路器)模式)来限制任何一个依赖服务的影响。
  • 通过近乎实时的指标、监控和告警优化故障发现时间。
  • 通过配置更改的低延迟传播和对 Hystrix 大部分方面的动态属性更改的支持来优化恢复时间,让我们可以通过低延迟反馈循环进行实时操作修改。
  • 防止整个依赖客户端执行中的故障,而不仅仅是网络流量中的故障。

6.Hystrix 的实现原理?

  • 将所有对外部系统(或“依赖项”)的调用包装在一个 HystrixCommandHystrixObservableCommand 对象中,该对象通常在单独的线程中执行(这是命令模式的一个示例)。
  • 超过您定义的阈值的超时调用。有一个默认值,但对于大多数依赖项,我们可以通过“properties”自定义设置这些超时,以便它们略高于每个依赖项测量的第99.5个百分位性能。
  • 为每个依赖项维护一个小线程池(或信号量);如果它已满,发往该依赖项的请求将立即被拒绝,而不是排队。
  • 测量成功、失败(客户端抛出的异常)、超时和线程拒绝。
  • 如果服务的错误百分比超过阈值,则手动或自动触发断路器以停止对特定服务的所有请求一段时间。
  • 当请求失败、被拒绝、超时或短路时执行回退逻辑。
  • 近乎实时地监控指标和配置变化。

当我们使用 Hystrix 来包装每个底层依赖项时,如上图所示的体系结构将更改改为类似于下图。每个依赖性彼此隔离,限制在发生延迟时它可能饱和的资源,并包含在回退逻辑中,该逻辑决定在依赖项中发生任何类型的故障时做出何种响应。

在这里插入图片描述

二、集成 Hystrix

1.Maven 依赖

<properties>
    <!-- build env -->
    <java.version>1.8</java.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>

    <!-- dependency version -->
    <lombok.version>1.18.18</lombok.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- Hystrix -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.4.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2020.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-dependencies</artifactId>
            <version>2.2.10.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.application.yml

简易版:

spring:
  main:
    allow-bean-definition-overriding: true

feign:
  hystrix:
    enabled: true

# Hystrix settings
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: THREAD
          thread:
            # 配置默认的超时时间,线程超时15秒,调用Fallback方法
            timeoutInMilliseconds: 15000
      metrics:
        rollingStats:
          timeInMilliseconds: 15000
      circuitBreaker:
        # 10秒内出现3个以上请求(已临近阀值),并且出错率在50%以上,开启断路器.断开服务,调用Fallback方法
        requestVolumeThreshold: 3
        sleepWindowInMilliseconds: 10000

完整版:

spring:
  main:
    allow-bean-definition-overriding: true

#default可替换
hystrix:
  command:
    default:
      execution:
        isolation:
          #线程池隔离还是信号量隔离 默认是THREAD 信号量是SEMAPHORE
          strategy: THREAD
          semaphore:
            #使用信号量隔离时,支持的最大并发数 默认10
            maxConcurrentRequests: 10
          thread:
            #command的执行的超时时间 默认是1000
            timeoutInMilliseconds: 2000
            #HystrixCommand.run()执行超时时是否被打断 默认true
            interruptOnTimeout: true
            #HystrixCommand.run()被取消时是否被打断 默认false
            interruptOnCancel: false
        timeout:
          #command执行时间超时是否抛异常 默认是true
          enabled: true
        fallback:
          #当执行失败或者请求被拒绝,是否会尝试调用hystrixCommand.getFallback()
          enabled: true
          isolation:
            semaphore:
              #如果并发数达到该设置值,请求会被拒绝和抛出异常并且fallback不会被调用 默认10
              maxConcurrentRequests: 10
      circuitBreaker:
        #用来跟踪熔断器的健康性,如果未达标则让request短路 默认true
        enabled: true
        #一个rolling window内最小的请求数。如果设为20,那么当一个rolling window的时间内
        #(比如说1个rolling window是10秒)收到19个请求,即使19个请求都失败,也不会触发circuit break。默认20
        requestVolumeThreshold: 5
        # 触发短路的时间值,当该值设为5000时,则当触发circuit break后的5000毫秒内
        #都会拒绝request,也就是5000毫秒后才会关闭circuit,放部分请求过去。默认5000
        sleepWindowInMilliseconds: 5000
        #错误比率阀值,如果错误率>=该值,circuit会被打开,并短路所有请求触发fallback。默认50
        errorThresholdPercentage: 50
        #强制打开熔断器,如果打开这个开关,那么拒绝所有request,默认false
        forceOpen: false
        #强制关闭熔断器 如果这个开关打开,circuit将一直关闭且忽略
        forceClosed: false
      metrics:
        rollingStats:
          #设置统计的时间窗口值的,毫秒值,circuit break 的打开会根据1个rolling window的统计来计算。若rolling window被设为10000毫秒,
          #则rolling window会被分成n个buckets,每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认10000
          timeInMilliseconds: 10000
          #设置一个rolling window被划分的数量,若numBuckets=10,rolling window=10000,
          #那么一个bucket的时间即1秒。必须符合rolling window % numberBuckets == 0。默认10
          numBuckets: 10
        rollingPercentile:
          #执行时是否enable指标的计算和跟踪,默认true
          enabled: true
          #设置rolling percentile window的时间,默认60000
          timeInMilliseconds: 60000
          #设置rolling percentile window的numberBuckets。逻辑同上。默认6
          numBuckets: 6
          #如果bucket size=100,window=10s,若这10s里有500次执行,
          #只有最后100次执行会被统计到bucket里去。增加该值会增加内存开销以及排序的开销。默认100
          bucketSize: 100
        healthSnapshot:
          #记录health 快照(用来统计成功和错误绿)的间隔,默认500ms
          intervalInMilliseconds: 500
      requestCache:
        #默认true,需要重载getCacheKey(),返回null时不缓存
        enabled: true
      requestLog:
        #记录日志到HystrixRequestLog,默认true
        enabled: true
  collapser:
    default:
      #单次批处理的最大请求数,达到该数量触发批处理,默认Integer.MAX_VALUE
      maxRequestsInBatch: 2147483647
      #触发批处理的延迟,也可以为创建批处理的时间+该值,默认10
      timerDelayInMilliseconds: 10
      requestCache:
        #是否对HystrixCollapser.execute() and HystrixCollapser.queue()的cache,默认true
        enabled: true
  threadpool:
    default:
      #并发执行的最大线程数,默认10
      coreSize: 10
      #Since 1.5.9 能正常运行command的最大支付并发数
      maximumSize: 10
      #BlockingQueue的最大队列数,当设为-1,会使用SynchronousQueue,值为正时使用LinkedBlcokingQueue。
      #该设置只会在初始化时有效,之后不能修改threadpool的queue size,除非reinitialising thread executor。
      #默认-1。
      maxQueueSize: -1
      #即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝。
      #因为maxQueueSize不能被动态修改,这个参数将允许我们动态设置该值。if maxQueueSize == -1,该字段将不起作用
      queueSizeRejectionThreshold: 5
      #Since 1.5.9 该属性使maximumSize生效,值须大于等于coreSize,当设置coreSize小于maximumSize
      allowMaximumSizeToDivergeFromCoreSize: false
      #如果corePoolSize和maxPoolSize设成一样(默认实现)该设置无效。
      #如果通过plugin(https://github.com/Netflix/Hystrix/wiki/Plugins)使用自定义实现,该设置才有用,默认1.
      keepAliveTimeMinutes: 1
      metrics:
        rollingStats:
          #线程池统计指标的时间,默认10000
          timeInMilliseconds: 10000
          #将rolling window划分为n个buckets,默认10
          numBuckets: 10

3.添加@EnableHystrix注解

@EnableHystrix
@SpringBootApplication
public class SpringbootDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }
}

4.HystrixConfig.java 配置类

import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * <p> @Title HystrixConfig
 * <p> @Description Hystric配置类
 *
 * @author ACGkaka
 * @date 2023/4/8 20:26
 */
@Configuration
public class HystrixConfig {

    // 用来拦截处理HystrixCommand注解的方法
    @Bean
    public HystrixCommandAspect hystrixCommandAspect() {
        return new HystrixCommandAspect();
    }

    // 用来向监控中心Dashboard发送stream信息
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

5.HystrixTestController.java 测试类

5.1)实现代码

import com.demo.common.Result;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p> @Title HystrixTestController
 * <p> @Description Hystric测试Controller
 *
 * @author ACGkaka
 * @date 2023/4/7 21:14
 */
@RestController
@RequestMapping("/hystrix")
// 指定默认熔断方法
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixTestController {

    /**
     * 用法1:直接使用@HystrixCommand注解,使用默认熔断方法
     */
    @HystrixCommand
    @GetMapping("/test1")
    public Result<Object> test1() throws InterruptedException {
        throw new RuntimeException("测试异常");
    }

    /**
     * 用法2:使用@HystrixCommand注解,指定熔断方法和超时时间
     */
    @HystrixCommand(
            fallbackMethod = "myFallback", // 降级的回调方法
            commandProperties = {
                    // 设置超时时间
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
            })
    @GetMapping("/test2")
    public Result<Object> test2() throws InterruptedException {
//        throw new RuntimeException("测试异常");
        for (int i = 0; i < 10; i++) {
            System.out.println(i + 1);
            Thread.sleep(1000);
        }
        return Result.succeed("测试成功");
    }

    /**
     * 该方法是一个熔断方法,当方法出现异常时,会调用该方法
     */
    public Result<Object> defaultFallback() {
        return Result.failed("@DefaultProperties指定的熔断方法");
    }

    /**
     * 该方法是一个熔断方法,当方法出现异常时,会调用该方法
     */
    public Result<Object> myFallback() {
        return Result.failed("@HystrixCommand指定的熔断方法");
    }
}

5.2)执行结果

访问地址:http://localhost:8080/hystrix/test1

在这里插入图片描述

访问地址:http://localhost:8080/hystrix/test2

在这里插入图片描述

在这里插入图片描述

5.3)总结

主要涉及到了三个注解:

  • @DefaultProperties:修饰类,用于指定默认的熔断方法,优先级低于 @HystrixCommand。
  • @HystrixCommand:修饰方法,用于指定熔断方法、熔断时间等。
  • @HystrixProperty:用于在Hystrix命令(HystrixCommand)上设置属性(property)。注解的name属性指定了要设置的属性名称,value属性指定了要设置的属性值。可以通过设置多个@HystrixProperty注解来同时配置多个属性。这样可以根据需要灵活地配置Hystrix命令的行为,例如设置超时时间、线程池大小、错误百分比阈值、休眠窗口时间等。

主要涉及到了三个属性:

  • defaultFallback:默认回退方法,当配置 fallbackMethod 项时忽略此配置,另外,默认回退方法不能有参数,返回值要与 Hystrix方法的返回值相同。
  • fallbackMethod:对Hystrix服务降级和熔断的方法,方法执行时熔断、错误、超时时会执行的回退方法,需要保持此方法与 Hystrix 方法的签名和返回值一致
  • commandProperties:用于为注解标注的 Hystrix 命令定义一组默认的属性值,例如设置超时时间、线程池大小、错误百分比阈值、休眠窗口时间等。

6.补充:@HystrixProperty 的常见用法

  • 设置熔断器在整个统计时间内是否开启的阀值。

    @HystrixProperty(name = "circuitBreaker.enabled", value = "true")
    
  • 设置在一个滚动窗口中,打开断路器的最少请求数。比如:如果值是20,在一个窗口内(比如10秒),收到19个请求,即使这19个请求都失败了,断路器也不会打开。

    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20")
    
  • 设置当出错率超过50%后熔断器启动。

    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
    
  • 设置熔断器工作时间,超过这个时间,先放一个请求进去,成功的话就关闭熔断,失败就再等一段时间。

    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000")
    
    
  • 设置 Hystrix 线程池的核心线程数。Hystrix 线程池用于执行 Hystrix 命令(HystrixCommand)的业务逻辑,它是一个线程池,用于处理请求并执行命令。coreSize 属性指定了线程池的核心线程数,即线程池中保持的最大活动线程数。通过调整 coreSize 属性的值,可以控制 Hystrix 线程池的并发度。较大的 coreSize 值可以支持更大的并发请求量,但也会消耗更多的系统资源。

    @HystrixProperty(name = "coreSize", value = "30")
    
  • 设置 BlockingQueue 的最大队列数,当设为-1,会使用 SynchronousQueue,值为正时使用 LinkedBlcokingQueue。

    @HystrixProperty(name = "maxQueueSize", value = "101")
    
  • 设置存活时间,单位:分钟。如果coreSize小于maximumSize,那么该属性控制一个线程从实用完成到被释放的时间。

    众所周知,如果线程池内核心线程数目都在忙碌,再有新的请求到达时,线程池容量可以被扩充到最大数量。

    等到线程池空闲后,多于核心数量的线程还会被回收,此值指定了线程被回收前的存活时间,默认为 2,即两分钟。

    @HystrixProperty(name = "keepAliveTimeMinutes", value = "2")
    
  • 设置队列拒绝的阈值,即使maxQueueSize还没有达到。

    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15")
    
  • 设置滑动统计的桶数量。

    设置一个rolling window被划分的数量,若numBuckets=10,rolling window=10000,那么一个bucket的时间即1秒。必须符合 rolling window % numberBuckets == 0,默认为1。

    @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "10")
    
  • 设置滑动窗口的统计时间,单位:毫秒。

    circuit break 的打开会根据1个rolling window的统计来计算。若rolling window被设为10000毫秒,则rolling window会被分成n个buckets,每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认为10000。

    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000")
    

三、Feign中Hystrix的使用

需要注意两点:

1)因为 Feign 中已经依赖了 Hystrix,所以当需要在 Feign 中使用 Hystrix 时,在 Maven 配置上不用做任何改动。

2)Hystrix 的熔断只是作用在服务调用这一端,所以我们只需要改动消费服务的相关代码就可以了。

下面我们就开始在 feign 中使用 Hystrix:

1.配置文件

application.yml 中添加如下内容:

# 开启熔断机制,默认false
feign:
  hystrix:
    enabled: true
  circuitbreaker:
    enabled: true

2.HystrixTestFeignClient.java Feign调用

import com.demo.common.Result;
import com.demo.feign.fallback.HystrixTestFeignClientFallBack;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * <p> @Title HystrixTestFeign
 * <p> @Description Hystrix测试Feign
 *
 * @author ACGkaka
 * @date 2023/4/23 13:42
 */
@FeignClient(name = "hystrix-demo", fallbackFactory = HystrixTestFeignClientFallBack.class)
public interface HystrixTestFeignClient {

    @GetMapping("/hystrixFeign/test1")
    Result<Object> test1();

    @GetMapping("/hystrixFeign/test")
    Result<Object> test();

}

3.HystrixTestFeignClientFallBack.java 熔断类

import com.demo.feign.HystrixTestFeignClient;
import com.demo.common.Result;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

/**
 * <p> @Title HystrixTestFeignClientFallBack
 * <p> @Description Hystrix测试Feign熔断类
 *
 * @author ACGkaka
 * @date 2023/4/23 13:55
 */
@Component
public class HystrixTestFeignClientFallBack implements FallbackFactory<HystrixTestFeignClient> {

    @Override
    public HystrixTestFeignClient create(Throwable cause) {
        return new HystrixTestFeignClient() {
            @Override
            public Result<Object> test1() {
                return Result.failed("调用失败,原因:" + cause.getMessage());
            }

            @Override
            public Result<Object> test() {
                return Result.failed("调用失败,原因:" + cause.getMessage());
            }
        };
    }
}

4.HystrixFeignTestController.java 测试类

4.1)实现代码

import com.demo.feign.HystrixTestFeignClient;
import com.demo.common.Result;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p> @Title HystrixFeignTestController
 * <p> @Description Hystrix测试Controller
 *
 * @author ACGkaka
 * @date 2023/4/23 14:17
 */
@RestController
@RequestMapping("/hystrixFeign")
public class HystrixFeignTestController {

    @Autowired
    private HystrixTestFeignClient hystrixTestFeignClient;

    /**
     * 测试feign调用
     */
    @GetMapping("/testFeign")
    public Result<Object> testFeign() {
        long start = System.currentTimeMillis();
        Result<Object> result = hystrixTestFeignClient.test();
        long end = System.currentTimeMillis();
        return result.setMessage(result.getMessage() + ",调用时间:" + (end - start) / 1000 + "秒");
    }

    /**
     * 测试feign调用
     */
    @GetMapping("/test1Feign")
    public Result<Object> test1Feign() {
        long start = System.currentTimeMillis();
        Result<Object> result = hystrixTestFeignClient.test1();
        long end = System.currentTimeMillis();
        return result.setMessage(result.getMessage() + ",调用时间:" + (end - start) / 1000 + "秒");
    }

    /**
     * 测试正常方法
     */
    @GetMapping("/test")
    public Result<Object> test() throws InterruptedException {
        // 配置中指定了默认15秒超时,这里设置了20秒超时,所以会调用熔断方法
        int i = 0;
        for (; i < 20; i++) {
            System.out.println(i + 1 + "秒");
            Thread.sleep(1000);
        }
        return Result.succeed("测试成功,等待时间:" + i + "秒");
    }

    /**
     * 直接抛出异常
     */
    @HystrixCommand
    @GetMapping("/test1")
    public Result<Object> test1() {
        throw new RuntimeException("测试异常");
    }

}

4.2)执行结果

测试1:测试feign超时熔断,访问地址:http://localhost:8081/hystrixFeign/testFeign

在这里插入图片描述

在这里插入图片描述

测试2:测试抛出异常熔断,访问地址:

在这里插入图片描述

4.3)总结

根据执行结果,我们可以看到:

  • 第1类超时熔断测试中,配置了15秒的熔断,超过15秒就会快速失败,但是不会影响通过feign调用的服务,已经触发执行的服务会继续执行剩余逻辑(跑完20秒)。

  • 第2类异常熔断测试中,在 fallbackFactory 指定的类中可以正常拿到异常的信息,并且封装更友好的提示出来。

hystrix还可以搭配 hystrix dashboard 在页面上实时看到熔断的服务,由于 hystrix 作为一个已经过期的组件,我们这里就不再继续深入了。

整理完毕,完结撒花~ 🌻





参考地址:

1.Spring Boot 集成 Hystrix,https://blog.csdn.net/qq_44750696/article/details/123961736

2.解决:@FeignClient的fallback、fallbackFactory不起作用解决,http://www.manongjc.com/detail/29-cqezmyvbjmfqjwp.html

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

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

相关文章

【CSS3】CSS3 伪元素选择器 ( 伪元素选择器语法简介 | 伪元素选择器权重计算 | 代码示例 )

文章目录 一、CSS3 伪元素选择器二、CSS3 伪元素选择器权重二、代码示例 一、CSS3 伪元素选择器 CSS3 伪元素选择器 : ::before 选择符 : 在 指定的标签元素内部的 前面 插入内容 ;::after 选择符 : 在指定的标签元素内部的 后面 插入内容 ; CSS3 伪元素选择器注意事项 : con…

QT里的网络通信简介

QTcpSocket类简介 QTcpSocket类提供了一个TCP套接字。TCP&#xff08;传输控制协议&#xff09;是一种可靠的、面向流的、面向连接的传输协议。它特别适合数据的连续传输。QTcpSocket是QAbstractSocket的一个子类&#xff0c;它允许您建立TCP连接和传输数据流。有关详细信息&a…

连接器信号完整性仿真教程 二

在连接器信号完整性仿真教程一中Step by Step演示了如何进行连接器信号完整性仿真&#xff0c;看完这片博文后应该可以做类似产品的仿真。如果说&#xff0c;看了这篇博文就学会了连接器信号完整性仿真&#xff0c;那就有点过了。有人也许会说信号完整性仿真难学&#xff0c;不…

利用GPT2 预测 福彩3d预测

使用GPT2预测福彩3D项目 个人总结彩票数据是随机的,可以预测到1-2个数字,但是有一两位总是随机的 该项目紧做模型学习用,通过该项目熟练模型训练调用生成过程. 福彩3D数据下载 https://www.17500.cn/getData/3d.TXT data数据格式 处理后数据格式 每行 2023 03 08 9 7 3 训…

Java入门教程||Java 继承||Java 重写(Override)与重载(Overload)

Java 继承 继承是所有 OOP 语言和 Java 语言不可缺少的组成部分。 继承是 Java 面向对象编程技术的一块基石&#xff0c;是面向对象的三大特征之一&#xff0c;也是实现软件复用的重要手段&#xff0c;继承可以理解为一个对象从另一个对象获取属性的过程。 如果类 A 是类 B …

玩机搞机----mtk芯片机型 另类制作备份线刷包的方式 读写分区等等

前面分享了几期高通和mtk芯片机型备份字库的几种方法教程。这些针对与很多没有线刷包资源的手机机型玩机操作。前面对接一个友商的mtk芯片杂牌机。和另外一个国外mtk芯片级都是来制作线刷包。因为&#xff0c;这些机型没有固件流出。而同一批机型中安卓版本高低不固定。支持的资…

谷歌TAG警告说俄罗斯黑客在乌克兰进行网络钓鱼攻击

与俄罗斯军事情报机构有关的精英黑客与针对乌克兰数百名用户的大批量网络钓鱼活动有关&#xff0c;以提取情报并影响与战争有关的公共言论。 谷歌的威胁分析小组&#xff08;TAG&#xff09;正在监测这个名为FROZENLAKE的行为者的活动&#xff0c;该小组表示&#xff0c;这些攻…

3105—IIS部署子站点

一、父站点 1—web.config配置 新增并设定location段落 <configuration><location path"." allowOverride"false" inheritInChildApplications"false"><system.webServer><handlers><add name"aspNetCore"…

科海思除COD树脂,大孔树脂,除COD专用树脂

一、产品介绍 Tulsimer A-722 MP具有控制孔径的大孔强碱性Ⅰ型阴离子交换树脂 Tulsimer A-722 MP 是一款具有便于颜色和有机物去除的控制孔径的&#xff0c;专门开发的大孔强碱性Ⅰ型阴离子交换树脂。 Tulsimer A-722 MP&#xff08;氯型&#xff09;专门应用于去除COD…

Vite与WebPack的对比,及解决了什么痛点,及什么是ESM?

一、简要 ESM&#xff0c;是指构成ESM规范的一系列的JavaScript特性或者API 1、首先要明确的是&#xff0c;Vite跟WebPack的优势只在开发环境。当把包部署到了生产环境后&#xff0c;大家都是一样的&#xff0c;甚至webpack的兼容性可能会更好。 这也是为什么有人提出&#x…

图像描述算法排位赛:SceneXplain 与 MiniGPT4 谁将夺得桂冠?

如果你对图像描述算法的未来感到好奇&#xff0c;本场“图像描述算法排位赛”绝对是你不能错过的&#xff01;在这场较量中&#xff0c;SceneXplain 和 MiniGPT-4 将会比试&#xff0c;谁将摘得这场比赛的桂冠&#xff1f; 背景介绍 在上篇文章中&#xff0c;我们介绍了图像描述…

C++类与对象—上

本期我们来学习类与对象 目录 面向过程和面向对象初步认识 类的引入 访问限定符 类的定义 封装 类的作用域 类的实例化 this指针 C语言和C实现Stack的对比 面向过程和面向对象初步认识 C 语言是 面向过程 的&#xff0c; 关注 的是 过程 &#xff0c;分析出求解问题的…

研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案

研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案 目录 研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案 一、简单介绍 二、计算机网络第七版(谢希仁) 第一章 课后答案 1、 计算机网络向用户可以提供哪些服务&#xff1f; 2、 试简述分组交换的要点。 3…

人工神经网络

&#x1f351; CV专栏 1. 单个神经元 &#x1f351; 神经网络 即 模型 &#x1f364; 输入 四个参数 --> 结果 &#x1f351; 模型训练(学习) 例子 &#x1f351; 模型的输入x 乘 权值ω 减去阈值θ --> 激活函数 f &#x1f351; 输出 yi &#xff08;向下传递 或 直…

一步步带你学习Python编程:从零开始的查缺补漏

在快节奏的生活中&#xff0c;很难找到时间来学习新的技能。但有时候&#xff0c;我们会突然发现自己有一些空闲时间&#xff0c;而又不想虚度光阴。无聊的时候&#xff0c;我们可以选择学习一项新技能来充实自己。最近&#xff0c;我就因为有些无聊&#xff0c;决定重新学习Py…

linux实现网络程序

1️⃣ 在linux下&#xff0c;通过套接字实现服务器和客户端的通信。 2️⃣ 实现单线程、多线程通信。或者实现线程池来通信。 3️⃣ 优化通信&#xff0c;增加守护进程。 有情提醒&#xff0c;类里面默认的函数是内联。内联函数在调用的地方展开&#xff0c;没有函数地址&…

【Springboot系列】Springboot整合Swagger3不简单

1、缘由 Swagger是一个根据代码注解生成接口文档的工具&#xff0c;减少和前端之间的沟通&#xff0c;前端同学看着文档就可以开发了&#xff0c;提升了效率&#xff0c;之前很少写swagger&#xff0c;这次自己动手写&#xff0c;还是有点麻烦&#xff0c;不怎么懂&#xff0c;…

外网SSH远程连接linux服务器「cpolar内网穿透」

文章目录 视频教程1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 转载自内网穿透工具的文章&#xff1a;无公网IP&#xff0c;SSH远程连接Linux CentOS服务器【内网穿透】 本次教程我们来实现如何在外公网环境下…

OpenGL入门教程之 纹理

引言 我们已经了解到&#xff0c;我们可以为每个顶点添加颜色来增加图形的细节&#xff0c;从而创建出有趣的图像。但是&#xff0c;如果想让图形看起来更真实&#xff0c;我们就必须有足够多的顶点&#xff0c;从而指定足够多的颜色。这将会产生很多额外开销&#xff0c;因为每…

【ArcGIS Pro二次开发】(23):用地编码和用地名称的规范性检查

在国空或村庄规划的编制过程中&#xff0c;随着规划用地的调整&#xff0c;经常会手动修改用地编码和用地名称&#xff0c;不可避免的会出现错误&#xff0c;如果单靠人工校对&#xff0c;累人又不能保证准确性。这个工具的目的就是检查用地编码和用地名称是否规范&#xff0c;…