|
|
@@ -0,0 +1,475 @@
|
|
|
+import com.netflix.hystrix.*;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author reghao
|
|
|
+ * @date 2025-07-20 11:01:33
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+public class HystrixTest {
|
|
|
+ /**
|
|
|
+ * 异常降级
|
|
|
+ * 非HystrixBadRequestException异常:当抛出HystrixBadRequestException时,
|
|
|
+ * 调用程序可以捕获异常,此时不会触发fallback,而其他异常则会触发fallback,
|
|
|
+ * 调用程序将获得fallback逻辑的返回结果。
|
|
|
+ */
|
|
|
+ static class HelloWorldExceptionCommand extends HystrixCommand<String> {
|
|
|
+ private final int n;
|
|
|
+
|
|
|
+ public HelloWorldExceptionCommand(int n) {
|
|
|
+ // 最小配置,指定groupKey
|
|
|
+ super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldExceptionGroup")));
|
|
|
+ this.n = n;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String run() throws Exception {
|
|
|
+ log.info(n + "-HelloWorldExceptionCommand A--> " + Thread.currentThread().getName());
|
|
|
+ // 制造异常
|
|
|
+ int i = 1 / n;
|
|
|
+ // 若异常被捕获则不会进入 getFallback()
|
|
|
+ /*try {
|
|
|
+ int i = 1 / n;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("异常:" + e.getMessage());
|
|
|
+ }*/
|
|
|
+
|
|
|
+ log.info(n + "-HelloWorldExceptionCommand B--> " + Thread.currentThread().getName());
|
|
|
+ return n + "执行成功";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String getFallback() {
|
|
|
+ log.error(n + "-异常降级! C--> " + Thread.currentThread().getName());
|
|
|
+ return n + "执行失败";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 超时降级
|
|
|
+ * run()/construct()运行超时:执行命令的方法超时,将会触发fallback。
|
|
|
+ */
|
|
|
+ static class HelloWorldTimeoutCommand extends HystrixCommand<String> {
|
|
|
+ private final int n;
|
|
|
+
|
|
|
+ public HelloWorldTimeoutCommand(int n) {
|
|
|
+ super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldTimeoutGroup"))
|
|
|
+ .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
|
|
|
+ /*
|
|
|
+ * execution.isolation.thread.timeoutInMilliseconds
|
|
|
+ * 设置调用者等待命令执行的超时限制,超过此时间,HystrixCommand被标记为TIMEOUT,
|
|
|
+ * 并执行回退逻辑。
|
|
|
+ * 默认值:1000(毫秒)
|
|
|
+ */
|
|
|
+ .withExecutionTimeoutInMilliseconds(500)
|
|
|
+ /*
|
|
|
+ * execution.timeout.enabled
|
|
|
+ * 设置HystrixCommand的执行是否有超时限制。
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withExecutionTimeoutEnabled(true)
|
|
|
+ /*
|
|
|
+ * execution.isolation.thread.interruptOnTimeout
|
|
|
+ * 设置HystrixCommand的执行是否在超时发生时被中断。
|
|
|
+ * 使用线程隔离时,是否对命令执行超时的线程调用中断(Thread.interrupt())操作。
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withExecutionIsolationThreadInterruptOnTimeout(false)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ this.n = n;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String run() throws Exception {
|
|
|
+ log.info(n + "-HelloWorldTimeoutCommand A--> " + Thread.currentThread().getName());
|
|
|
+ if (n == 0) {
|
|
|
+ // 设置超时
|
|
|
+ Thread.sleep(1000);
|
|
|
+ }
|
|
|
+ // 设置withExecutionIsolationThreadInterruptOnTimeout(false)后面代码将会继续执行
|
|
|
+ log.info(n + "-HelloWorldTimeoutCommand B--> " + Thread.currentThread().getName());
|
|
|
+ return n + "执行成功";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String getFallback() {
|
|
|
+ log.error("超时降级! C--> " + Thread.currentThread().getName());
|
|
|
+ return n + "执行失败";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 触发熔断器熔断
|
|
|
+ * 熔断器开启:当熔断器处于开启的状态,将会触发fallback。
|
|
|
+ */
|
|
|
+ static class HelloWorldBreakerCommand extends HystrixCommand<String> {
|
|
|
+ private final int n;
|
|
|
+
|
|
|
+ public HelloWorldBreakerCommand(int n) {
|
|
|
+ //最小配置,指定groupKey
|
|
|
+ super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldBreakerGroup"))
|
|
|
+ .andCommandPropertiesDefaults(
|
|
|
+ HystrixCommandProperties.Setter()
|
|
|
+ /*
|
|
|
+ * execution.isolation.thread.timeoutInMilliseconds
|
|
|
+ * 设置调用者等待命令执行的超时限制,超过此时间,HystrixCommand被标记为TIMEOUT,
|
|
|
+ * 并执行回退逻辑。
|
|
|
+ * 默认值:1000(毫秒)
|
|
|
+ */
|
|
|
+ .withExecutionTimeoutInMilliseconds(1000)
|
|
|
+ /*
|
|
|
+ * execution.isolation.thread.interruptOnTimeout
|
|
|
+ * 设置HystrixCommand的执行是否在超时发生时被中断。
|
|
|
+ * 使用线程隔离时,是否对命令执行超时的线程调用中断(Thread.interrupt())操作。
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withExecutionIsolationThreadInterruptOnTimeout(true)
|
|
|
+ // ** 断路器(Circuit Breaker)属性配置 **
|
|
|
+ /*
|
|
|
+ * circuitBreaker.enabled
|
|
|
+ * 设置断路器是否生效
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withCircuitBreakerEnabled(true)
|
|
|
+ /*
|
|
|
+ * circuitBreaker.requestVolumeThreshold
|
|
|
+ * 设置在一个滚动窗口中,打开断路器的最少请求数。比如:如果值是20,在一个窗口内(比如10秒),收到19个请求,即使这19个请求都失败了,断路器也不会打开。
|
|
|
+ * 默认值:20
|
|
|
+ */
|
|
|
+ .withCircuitBreakerRequestVolumeThreshold(6)
|
|
|
+ /*
|
|
|
+ * circuitBreaker.sleepWindowInMilliseconds
|
|
|
+ * 设置在断路器被打开,拒绝请求到再次尝试请求的时间间隔。
|
|
|
+ * 默认值:5000(毫秒)
|
|
|
+ */
|
|
|
+ .withCircuitBreakerSleepWindowInMilliseconds(3000)
|
|
|
+ /*
|
|
|
+ * circuitBreaker.errorThresholdPercentage
|
|
|
+ * 设置打开断路器并启动回退逻辑的错误比率。
|
|
|
+ * (这个参数的效果受到circuitBreaker.requestVolumeThreshold和滚动时间窗口的时间长度影响)
|
|
|
+ * 默认值:50(%)
|
|
|
+ */
|
|
|
+ .withCircuitBreakerErrorThresholdPercentage(50)
|
|
|
+ )
|
|
|
+ //设置核心线程池的大小
|
|
|
+ .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(20))
|
|
|
+ );
|
|
|
+ this.n = n;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String run() throws Exception {
|
|
|
+ log.info(n + "-HelloWorldTimeoutCommand A--> " + Thread.currentThread().getName());
|
|
|
+ if (n > 0) {
|
|
|
+ // 设置超时
|
|
|
+ Thread.sleep(1000);
|
|
|
+ }
|
|
|
+ // 设置withExecutionIsolationThreadInterruptOnTimeout(true)后面代码将中断执行
|
|
|
+ log.info(n + "-HelloWorldTimeoutCommand B--> " + Thread.currentThread().getName());
|
|
|
+ return n + "执行成功";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String getFallback() {
|
|
|
+ log.error("熔断降级! C--> " + Thread.currentThread().getName());
|
|
|
+ return n + "执行失败";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 线程池/信号量已满
|
|
|
+ * 当线程池/信号量已满的状态,将会触发fallback。
|
|
|
+ */
|
|
|
+ static class HelloWorldThreadPoolCommand extends HystrixCommand<String> {
|
|
|
+ private final int n;
|
|
|
+
|
|
|
+ public HelloWorldThreadPoolCommand(int n) {
|
|
|
+ super(Setter
|
|
|
+ // *** 基础属性配置 ***
|
|
|
+ /*
|
|
|
+ * CommandGroup是每个命令最少配置的必选参数,在不指定ThreadPoolKey的情况下,
|
|
|
+ * 字面值用于对不同依赖的线程池/信号区分,也就是在不指定ThreadPoolKey的情况下,
|
|
|
+ * CommandGroup用于指定线程池的隔离。命令分组用于对依赖操作分组,便于统计、汇总等。
|
|
|
+ */
|
|
|
+ .withGroupKey(HystrixCommandGroupKey.Factory.asKey("helloWorldThreadPoolGroup"))
|
|
|
+ /*
|
|
|
+ * CommandKey是作为依赖命名,一般来说每个CommandKey代表一个依赖抽象,
|
|
|
+ * 相同的依赖要使用相同的CommandKey名称。依赖隔离的根本就是对相同CommandKey的依赖做隔离。
|
|
|
+ * 不同的依赖隔离最好使用不同的线程池(定义不同的ThreadPoolKey)。
|
|
|
+ * 从HystrixCommand源码的注释也可以看到CommandKey也用于对依赖操作统计、汇总等。
|
|
|
+ */
|
|
|
+ .andCommandKey(HystrixCommandKey.Factory.asKey("helloWorldThreadPoolCommand"))
|
|
|
+ /*
|
|
|
+ * ThreadPoolKey简单来说就是依赖隔离使用的线程池的键值。
|
|
|
+ * 当对同一业务依赖做隔离时使用CommandGroup做区分,
|
|
|
+ * 但是对同一依赖的不同远程调用如(一个是redis 一个是http),可以使用HystrixThreadPoolKey做隔离区分。
|
|
|
+ * 虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用HystrixThreadPoolKey区分。
|
|
|
+ * (对于每个不同的HystrixThreadPoolKey建议使用不同的CommandKey)
|
|
|
+ */
|
|
|
+ .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("helloWorldThreadPool"))
|
|
|
+ // *** 设置命令属性配置默认值 ***
|
|
|
+ .andCommandPropertiesDefaults(
|
|
|
+ HystrixCommandProperties.Setter()
|
|
|
+ // ** 执行属性 **
|
|
|
+ /*
|
|
|
+ * execution.isolation.strategy
|
|
|
+ * 用于设置HystrixCommand执行的隔离策略,有两种选项:
|
|
|
+ * THREAD —— 在固定大小线程池中,以单独线程执行,并发请求数受限于线程池大小。
|
|
|
+ * SEMAPHORE —— 在调用线程中执行,通过信号量来限制并发量。
|
|
|
+ * 默认值:THREAD(ExecutionIsolationStrategy.THREAD)可选值:THREAD,SEMAPHORE
|
|
|
+ */
|
|
|
+ .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
|
|
|
+ /*
|
|
|
+ * execution.isolation.thread.timeoutInMilliseconds
|
|
|
+ * 设置调用者等待命令执行的超时限制,超过此时间,HystrixCommand被标记为TIMEOUT,
|
|
|
+ * 并执行回退逻辑。
|
|
|
+ * 默认值:1000(毫秒)
|
|
|
+ */
|
|
|
+ .withExecutionTimeoutInMilliseconds(1000)
|
|
|
+ /*
|
|
|
+ * execution.timeout.enabled
|
|
|
+ * 设置HystrixCommand的执行是否有超时限制。
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withExecutionTimeoutEnabled(false)
|
|
|
+ /*
|
|
|
+ * execution.isolation.thread.interruptOnTimeout
|
|
|
+ * 设置HystrixCommand的执行是否在超时发生时被中断。
|
|
|
+ * 使用线程隔离时,是否对命令执行超时的线程调用中断(Thread.interrupt())操作。
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withExecutionIsolationThreadInterruptOnTimeout(true)
|
|
|
+ /*
|
|
|
+ * execution.isolation.semaphore.maxConcurrentRequests
|
|
|
+ * 设置当使用ExecutionIsolationStrategy.SEMAPHORE时,HystrixCommand执行方法允许的最大请求数。
|
|
|
+ * 如果达到最大并发数时,后续请求会被拒绝。
|
|
|
+ * 信号量应该是容器(比如Tomcat)线程池一小部分,不能等于或者略小于容器线程池大小,否则起不到保护作用。
|
|
|
+ * 默认值:10
|
|
|
+ */
|
|
|
+ .withExecutionIsolationSemaphoreMaxConcurrentRequests(10)
|
|
|
+ // ** 回退属性 **
|
|
|
+ // 下面的属性控制HystrixCommand.getFallback()执行。
|
|
|
+ // 这些属性对ExecutionIsolationStrategy.THREAD和ExecutionIsolationStrategy.SEMAPHORE都有效。
|
|
|
+ /*
|
|
|
+ * fallback.isolation.semaphore.maxConcurrentRequests
|
|
|
+ * 设置调用线程产生的HystrixCommand.getFallback()方法的允许最大请求数目。
|
|
|
+ * 如果达到最大并发数目,后续请求将会被拒绝,如果没有实现回退,则抛出异常。
|
|
|
+ * (这里需要注意一点,这个变量的命名不是很规范,它实际上对THREAD和SEMAPHORE两种隔离策略都生效)
|
|
|
+ * 默认值:10
|
|
|
+ */
|
|
|
+ .withFallbackIsolationSemaphoreMaxConcurrentRequests(10)
|
|
|
+ /*
|
|
|
+ * fallback.enabled
|
|
|
+ * 该属性决定当前的调用故障或者拒绝发生时,是否调用HystrixCommand.getFallback()。
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withFallbackEnabled(true)
|
|
|
+ // ** 断路器(Circuit Breaker)属性配置 **
|
|
|
+ /*
|
|
|
+ * circuitBreaker.enabled
|
|
|
+ * 设置断路器是否生效
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withCircuitBreakerEnabled(true)
|
|
|
+ /*
|
|
|
+ * circuitBreaker.requestVolumeThreshold
|
|
|
+ * 设置在一个滚动窗口中,打开断路器的最少请求数。比如:如果值是20,在一个窗口内(比如10秒),收到19个请求,即使这19个请求都失败了,断路器也不会打开。
|
|
|
+ * 默认值:20
|
|
|
+ */
|
|
|
+ .withCircuitBreakerRequestVolumeThreshold(5)
|
|
|
+ /*
|
|
|
+ * circuitBreaker.sleepWindowInMilliseconds
|
|
|
+ * 设置在断路器被打开,拒绝请求到再次尝试请求的时间间隔。
|
|
|
+ * 默认值:5000(毫秒)
|
|
|
+ */
|
|
|
+ .withCircuitBreakerSleepWindowInMilliseconds(5000)
|
|
|
+ /*
|
|
|
+ * circuitBreaker.errorThresholdPercentage
|
|
|
+ * 设置打开断路器并启动回退逻辑的错误比率。
|
|
|
+ * (这个参数的效果受到circuitBreaker.requestVolumeThreshold和滚动时间窗口的时间长度影响)
|
|
|
+ * 默认值:50(%)
|
|
|
+ */
|
|
|
+ .withCircuitBreakerErrorThresholdPercentage(50)
|
|
|
+ /*
|
|
|
+ * circuitBreaker.forceOpen
|
|
|
+ * 如果该属性设置为true,强制断路器进入打开状态,将会拒绝所有的请求。
|
|
|
+ * 该属性优先级比circuitBreaker.forceClosed高
|
|
|
+ * 默认值:false
|
|
|
+ */
|
|
|
+ .withCircuitBreakerForceOpen(false)
|
|
|
+ /*
|
|
|
+ * circuitBreaker.forceClosed
|
|
|
+ * 如果该属性设置为true,强制断路器进入关闭状态,将会允许所有的请求,无视错误率。
|
|
|
+ * 默认值:false
|
|
|
+ */
|
|
|
+ .withCircuitBreakerForceClosed(false)
|
|
|
+ // ** 请求上下文属性配置 **
|
|
|
+ /*
|
|
|
+ * requestCache.enabled
|
|
|
+ * 设置HystrixCommand.getCacheKey()是否启用,由HystrixRequestCache通过请求缓存提供去重复数据功能。
|
|
|
+ * (请求结果缓存需要配合HystrixRequestContext使用,具体应用可以自行查阅)
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withRequestCacheEnabled(true)
|
|
|
+ /*
|
|
|
+ * requestLog.enabled
|
|
|
+ * 设置HystrixCommand执行和事件是否要记录日志到HystrixRequestLog。
|
|
|
+ * 默认值:true
|
|
|
+ */
|
|
|
+ .withRequestLogEnabled(true)
|
|
|
+ )
|
|
|
+ // *** 设置线程池属性配置默认值 ***
|
|
|
+ .andThreadPoolPropertiesDefaults(
|
|
|
+ HystrixThreadPoolProperties.Setter()
|
|
|
+ /*
|
|
|
+ * coreSize
|
|
|
+ * 设置核心线程池的大小(这个值和ThreadPoolExecutor的coreSize的含义不一样)
|
|
|
+ * 默认值:10
|
|
|
+ */
|
|
|
+ .withCoreSize(10)
|
|
|
+ /*
|
|
|
+ * maximumSize
|
|
|
+ * 1.5.9新增属性,设置线程池最大值。
|
|
|
+ * 这个是在不开始拒绝HystrixCommand的情况下支持的最大并发数。
|
|
|
+ * 这个属性起作用的前提是设置了allowMaximumSizeToDivergeFromCoreSize。
|
|
|
+ * 1.5.9之前,核心线程池大小和最大线程池大小总是相同的。
|
|
|
+ * 默认值:10
|
|
|
+ */
|
|
|
+ .withMaximumSize(10)
|
|
|
+ /*
|
|
|
+ * maxQueueSize
|
|
|
+ * 设置BlockingQueue最大的队列值。如果设置为-1,
|
|
|
+ * 那么使用SynchronousQueue,否则正数将会使用LinkedBlockingQueue。
|
|
|
+ * 如果需要去除这些限制,允许队列动态变化,可以参考queueSizeRejectionThreshold属性。
|
|
|
+ * 修改SynchronousQueue和LinkedBlockingQueue需要重启。
|
|
|
+ * 默认值:-1
|
|
|
+ */
|
|
|
+ .withMaxQueueSize(-1)
|
|
|
+ /*
|
|
|
+ * queueSizeRejectionThreshold
|
|
|
+ * 设置队列拒绝的阈值—-一个人为设置的拒绝访问的最大队列值,即使当前队列元素还没达到maxQueueSize。
|
|
|
+ * 当将一个线程放入队列等待执行时,HystrixCommand使用该属性。
|
|
|
+ * 注意:如果maxQueueSize设置为-1,该属性不可用。
|
|
|
+ * 默认值:5
|
|
|
+ */
|
|
|
+ .withQueueSizeRejectionThreshold(5)
|
|
|
+ /*
|
|
|
+ * keepAliveTimeMinutes
|
|
|
+ * 设置存活时间,单位分钟。如果coreSize小于maximumSize,那么该属性控制一个线程从实用完成到被释放的时间。
|
|
|
+ * 默认值:1
|
|
|
+ */
|
|
|
+ .withKeepAliveTimeMinutes(1)
|
|
|
+ /*
|
|
|
+ * allowMaximumSizeToDivergeFromCoreSize
|
|
|
+ * 在1.5.9中新增的属性。该属性允许maximumSize起作用。属性值可以等于或者大于coreSize值,
|
|
|
+ * 设置coreSize小于maximumSize的线程池能够支持maximumSize的并发数,
|
|
|
+ * 但是会将不活跃的线程返回到系统中去。
|
|
|
+ * 默认值:false
|
|
|
+ */
|
|
|
+ .withAllowMaximumSizeToDivergeFromCoreSize(false)
|
|
|
+ /*
|
|
|
+ * metrics.rollingStats.timeInMilliseconds
|
|
|
+ * 设置统计的滚动窗口的时间段大小。该属性是线程池保持指标时间长短。
|
|
|
+ * 默认值:10000(毫秒)
|
|
|
+ */
|
|
|
+ .withMetricsRollingStatisticalWindowInMilliseconds(10000)
|
|
|
+ /*
|
|
|
+ * metrics.rollingStats.numBuckets
|
|
|
+ * 设置滚动的统计窗口被分成的桶(bucket)的数目。
|
|
|
+ * 注意:”metrics.rollingStats.timeInMilliseconds % metrics.rollingStats.numBuckets == 0”必须为true,否则会抛出异常。
|
|
|
+ * 默认值:10
|
|
|
+ */
|
|
|
+ .withMetricsRollingStatisticalWindowBuckets(10)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ this.n = n;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String run() throws Exception {
|
|
|
+ log.info(n + "-HelloWorldThreadPoolCommand A--> " + Thread.currentThread().getName());
|
|
|
+ Thread.sleep(10000);
|
|
|
+ log.info(n + "-HelloWorldThreadPoolCommand B--> " + Thread.currentThread().getName());
|
|
|
+ return n + "执行完毕";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String getFallback() {
|
|
|
+ log.error("线程池/信号量已满 FALLBACK --> !");
|
|
|
+ return "FALLBACK";
|
|
|
+ }
|
|
|
+
|
|
|
+ static class ThreadRunner extends Thread {
|
|
|
+ private int i;
|
|
|
+
|
|
|
+ public ThreadRunner(int i) {
|
|
|
+ this.i = i;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ log.info(new HelloWorldThreadPoolCommand(i).execute());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void test1() throws Exception {
|
|
|
+ for (int i = 0; i < 100; i++) {
|
|
|
+ if (i == 3) {
|
|
|
+ i = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ HelloWorldExceptionCommand command = new HelloWorldExceptionCommand(i);
|
|
|
+ log.info(command.execute());
|
|
|
+ Thread.sleep(1000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void test2() throws Exception {
|
|
|
+ for (int i = 0; i < 100; i++) {
|
|
|
+ if (i == 5) {
|
|
|
+ i = 0;
|
|
|
+ }
|
|
|
+ HelloWorldTimeoutCommand command = new HelloWorldTimeoutCommand(i);
|
|
|
+ // 超时执行getFallback
|
|
|
+ log.info(command.execute());
|
|
|
+
|
|
|
+ Thread.sleep(1000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void test3() throws Exception {
|
|
|
+ for (int i = 0; i < 100; i++) {
|
|
|
+ try {
|
|
|
+ if (i == 10) {
|
|
|
+ i = 0;
|
|
|
+ Thread.sleep(1000);
|
|
|
+ }
|
|
|
+ log.info(new HelloWorldBreakerCommand(i).execute());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("异常:" + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void test4() throws Exception {
|
|
|
+ // 关闭HystrixCommand执行的超时限制,设置withExecutionTimeoutEnabled(false)
|
|
|
+ // withCoreSize(10)
|
|
|
+ for (int i = 0; i < 100; i++) {
|
|
|
+ Thread thread = new HelloWorldThreadPoolCommand.ThreadRunner(i);
|
|
|
+ thread.start();
|
|
|
+ Thread.sleep(500);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) throws Exception {
|
|
|
+ //test1();
|
|
|
+ System.out.println("---------------------------------------------");
|
|
|
+ //test2();
|
|
|
+ System.out.println("---------------------------------------------");
|
|
|
+ test3();
|
|
|
+ System.out.println("---------------------------------------------");
|
|
|
+ //test4();
|
|
|
+ }
|
|
|
+}
|