springcloud 入门系列(六)Hystrix-属性配置

昨天我们介绍了如何使用hystrix,并且对其有了初步的认识,今天我们进一步来了解hystrix.

下面是对hystrx 的设计目标和原则的一些描述,摘自网络:

https://www.cnblogs.com/cjsblog/p/9391819.html,也是hystrix在github 上的wiki翻译:

Hystrix被设计的目标是:

  1. 对通过第三方客户端库访问的依赖项(通常是通过网络)的延迟和故障进行保护和控制。
  2. 在复杂的分布式系统中阻止级联故障。
  3. 快速失败,快速恢复。
  4. 回退,尽可能优雅地降级。
  5. 启用近实时监控、警报和操作控制。

Hystrix设计原则是什么

  • 防止任何单个依赖项耗尽所有容器(如Tomcat)用户线程。
  • 甩掉包袱,快速失败而不是排队。
  • 在任何可行的地方提供回退,以保护用户不受失败的影响。
  • 使用隔离技术(如隔离板、泳道和断路器模式)来限制任何一个依赖项的影响。
  • 通过近实时的度量、监视和警报来优化发现时间。
  • 通过配置的低延迟传播来优化恢复时间。
  • 支持对Hystrix的大多数方面的动态属性更改,允许使用低延迟反馈循环进行实时操作修改。
  • 避免在整个依赖客户端执行中出现故障,而不仅仅是在网络流量中。

Hystrix是如何实现它的目标的

  1. 用一个HystrixCommand 或者 HystrixObservableCommand (这是命令模式的一个例子)包装所有的对外部系统(或者依赖)的调用,典型地它们在一个单独的线程中执行
  2. 调用超时时间比你自己定义的阈值要长。有一个默认值,对于大多数的依赖项你是可以自定义超时时间的。
  3. 为每个依赖项维护一个小的线程池(或信号量);如果线程池满了,那么该依赖性将会立即拒绝请求,而不是排队。
  4. 调用的结果有这么几种:成功、失败(客户端抛出异常)、超时、拒绝。
  5. 在一段时间内,如果服务的错误百分比超过了一个阈值,就会触发一个断路器来停止对特定服务的所有请求,无论是手动的还是自动的。
  6. 当请求失败、被拒绝、超时或短路时,执行回退逻辑。
  7. 近实时监控指标和配置变化。

通过上面的介绍,我们知道hystrix 有多种方式来实现服务的隔离,可以通过线程和信号量来控制,默认是线程池隔离实现。下面我们来看下@HystrixCommand注解都有哪些属性,并且如何来设置属性值:

我们先看下他的源码:

/**
 * Copyright 2012 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.netflix.hystrix.contrib.javanica.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
 * This annotation used to specify some methods which should be processes as hystrix commands.
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HystrixCommand {

    /**
     * The command group key is used for grouping together commands such as for reporting,
     * alerting, dashboards or team/library ownership.
     * <p/>
     * default => the runtime class name of annotated method
     *
     * @return group key
     */
    String groupKey() default "";

    /**
     * Hystrix command key.
     * <p/>
     * default => the name of annotated method. for example:
     * <code>
     *     ...
     *     @HystrixCommand
     *     public User getUserById(...)
     *     ...
     *     the command name will be: 'getUserById'
     * </code>
     *
     * @return command key
     */
    String commandKey() default "";

    /**
     * The thread-pool key is used to represent a
     * HystrixThreadPool for monitoring, metrics publishing, caching and other such uses.
     *
     * @return thread pool key
     */
    String threadPoolKey() default "";

    /**
     * Specifies a method to process fallback logic.
     * A fallback method should be defined in the same class where is HystrixCommand.
     * Also a fallback method should have same signature to a method which was invoked as hystrix command.
     * for example:
     * <code>
     *      @HystrixCommand(fallbackMethod = "getByIdFallback")
     *      public String getById(String id) {...}
     *
     *      private String getByIdFallback(String id) {...}
     * </code>
     * Also a fallback method can be annotated with {@link HystrixCommand}
     * <p/>
     * default => see {@link com.netflix.hystrix.contrib.javanica.command.GenericCommand#getFallback()}
     *
     * @return method name
     */
    String fallbackMethod() default "";

    /**
     * Specifies command properties.
     *
     * @return command properties
     */
    HystrixProperty[] commandProperties() default {};

    /**
     * Specifies thread pool properties.
     *
     * @return thread pool properties
     */
    HystrixProperty[] threadPoolProperties() default {};

    /**
     * Defines exceptions which should be ignored.
     * Optionally these can be wrapped in HystrixRuntimeException if raiseHystrixExceptions contains RUNTIME_EXCEPTION.
     *
     * @return exceptions to ignore
     */
    Class<? extends Throwable>[] ignoreExceptions() default {};

    /**
     * Specifies the mode that should be used to execute hystrix observable command.
     * For more information see {@link ObservableExecutionMode}.
     *
     * @return observable execution mode
     */
    ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER;

    /**
     * When includes RUNTIME_EXCEPTION, any exceptions that are not ignored are wrapped in HystrixRuntimeException.
     *
     * @return exceptions to wrap
     */
    HystrixException[] raiseHystrixExceptions() default {};

    /**
     * Specifies default fallback method for the command. If both {@link #fallbackMethod} and {@link #defaultFallback}
     * methods are specified then specific one is used.
     * note: default fallback method cannot have parameters, return type should be compatible with command return type.
     *
     * @return the name of default fallback method
     */
    String defaultFallback() default "";
}

源码中对属性的意思已经做了详尽的注释,这里不再累述,下面我们就来做一些我们实际当中大概率需要用到的配置做实验,比如设定使用线程池隔离,设置线程池的参数,以及服务执行超时时间;

先看代码:

@HystrixCommand(commandKey = "hello",fallbackMethod = "fallback",threadPoolProperties = {
            @HystrixProperty(name = "coreSize",value = "2"), // 线程核心数目
            @HystrixProperty(name = "maxQueueSize",value="3") // 线程池队列大小

    },commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"), // 使用线程池隔离
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000" ) // hystrix 超时时间
    }
    )
    public String hello(String name) throws InterruptedException {
        Stopwatch stopwatch = Stopwatch.createStarted();
        Random random = new Random();
        int r = random.nextInt(3000);
        Thread.sleep(r);
        log.info("服务耗时:{}",stopwatch.stop());
        return "hello world!" + name;
    }

    /**
     * 错误回调方法参数签名必须与原方法一致
     *
     * @param name
     * @return
     */
    public String fallback(String name, Throwable e) {
        log.info("这是造成服务降级的异常信息:{}",name, e);
        return "this is fallback message! ";
    }

我们设置服务启用线程池进行隔离,并且设置线程池大小为2,线程等待队列为3,以及超时时间1s。我们让服务线程随机睡眠3s内,来测试超时,我们启动服务并发送请求,查看控制台:

https://mmbiz.qpic.cn/mmbiz_png/StSSauj2rMria8AP4IXpMYxcHvJtKw84tE6L2MgTibibZFZ6bRVuchDEP52ibWEjU7jRrJAmUC1AuFAhRwHC2Zw7Xg/640?wx_fmt=png

我们看到超时,fallback 方法被执行,并返回兜底数据。我们再修改线程睡眠时间来验证线程隔离。

同时我们再设置启动并发线程来调用接口来验证线程池配置的参数:

@RestController
public class Controller {

    @Autowired
    private HelloServiceWithFallback helloServiceWithFallback;

    @GetMapping("test")
    public String test(Integer times) throws InterruptedException {

        for (int i = 0;i<times; i++){
            RunnAlble runnAlble = new RunnAlble();
            new Thread(runnAlble).start();
        }
        return helloServiceWithFallback.hello("ethan!!");
    }

    class RunnAlble implements Runnable{

        @Override
        public void run() {
            try {
                helloServiceWithFallback.hello("ethan!!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

我们设置请求参数time=4,也就是我们同时启动5个线程去执行服务,理论上可能会出现超时情况:

https://mmbiz.qpic.cn/mmbiz_png/StSSauj2rMria8AP4IXpMYxcHvJtKw84tqNk0J6926qbT4Pju0sD80EHRiaCJGs9880NtEkJqqhjItqRsI58micBQ/640?wx_fmt=png

 

果然超时了,但是为什么会出现超时呢,因为我们的线程数目设置的是2,超过2个的请求会进入队列等待,所以就会出现超时情况。

下面我们设置times=5 也就是会生成6个线程去请求,我们看下测试结果:

https://mmbiz.qpic.cn/mmbiz_png/StSSauj2rMria8AP4IXpMYxcHvJtKw84t2giaCZB7mfn2qY4O3icuxMqSqlIKLkKQlIBgXR4kD7FOhNL5VCKUz2NA/640?wx_fmt=png

看到后面的请求被拒绝执行了,请求数目大于(coreSize+maxQueueSize)数目就会直接拒绝请求返回fallback方法结果

我们再来修改配置,测试断路器的属性配置;

 

 @HystrixCommand(commandKey = "hello",fallbackMethod = "fallback",threadPoolProperties = {
            @HystrixProperty(name = "coreSize",value = "2"), // 线程核心数目
            @HystrixProperty(name = "maxQueueSize",value="3") // 线程池队列大小

    },commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"), // 使用线程池隔离
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000" ) ,// hystrix 超时时间
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true" ), //开启熔断器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "3" ) // 窗口时间内多少个请求失败了,会打开断路器
    }
    )
    public String hello(String name) throws InterruptedException {
        log.info("hello start!");
        Stopwatch stopwatch = Stopwatch.createStarted();
//        Random random = new Random();
//        int r = random.nextInt(5);
        Thread.sleep(1200);
        log.info("服务耗时:{}",stopwatch.stop());
        return "hello world!" + name;
    }

    /**
     * 错误回调方法参数签名必须与原方法一致
     *
     * @param name
     * @return
     */
    public String fallback(String name, Throwable e) {
        log.info("这是造成服务降级的异常信息:{}",name, e);
        return "this is fallback message! ";
    }

这次我们修改了线程睡眠时间,让其超时,新增参数:

开启短路器,并且设置窗口时间内5次请求失败则打开断路器,也就是说,只要窗口时间内5次请求都失败了,则后面直接进入fallback方法(该服务被熔断了),设置times=5,再看控制台日志输出:

 

2019-07-17 17:27:17.333  INFO 3532 --- [nio-8888-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'2019-07-17 17:27:17.333  INFO 3532 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'2019-07-17 17:27:17.339  INFO 3532 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 6 ms2019-07-17 17:27:17.586  INFO 3532 --- [      Thread-19] c.e.hystrix.HelloServiceWithFallback     : 这是造成服务降级的异常信息:ethan!!​java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@cab906f rejected from java.util.concurrent.ThreadPoolExecutor@206f407[Running, pool size = 1, active threads = 1, queued tasks = 3, completed tasks = 0]  at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047) ~[na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823) ~[na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369) ~[na:1.8.0_131]  at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) ~[na:1.8.0_131]  at com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler$ThreadPoolWorker.schedule(HystrixContextScheduler.java:172) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler$HystrixContextSchedulerWorker.schedule(HystrixContextScheduler.java:106) ~[hystrix-core-1.5.18.jar:1.5.18]  at rx.internal.operators.OperatorSubscribeOn.call(OperatorSubscribeOn.java:50) ~[rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OperatorSubscribeOn.call(OperatorSubscribeOn.java:30) ~[rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30) [rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30) [rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30) [rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35) [rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33) [rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30) [rxjava-1.3.8.jar:1.3.8]  at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.3.8.jar:1.3.8]  at rx.Observable.subscribe(Observable.java:10423) [rxjava-1.3.8.jar:1.3.8]  at rx.Observable.subscribe(Observable.java:10390) [rxjava-1.3.8.jar:1.3.8]  at rx.internal.operators.BlockingOperatorToFuture.toFuture(BlockingOperatorToFuture.java:51) [rxjava-1.3.8.jar:1.3.8]  at rx.observables.BlockingObservable.toFuture(BlockingObservable.java:410) [rxjava-1.3.8.jar:1.3.8]  at com.netflix.hystrix.HystrixCommand.queue(HystrixCommand.java:378) [hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.HystrixCommand.execute(HystrixCommand.java:344) [hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.contrib.javanica.command.CommandExecutor.execute(CommandExecutor.java:52) [hystrix-javanica-1.5.18.jar:1.5.18]  at com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect.methodsAnnotatedWithHystrixCommand(HystrixCommandAspect.java:101) [hystrix-javanica-1.5.18.jar:1.5.18]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]  at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) [spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) [spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]  at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) [spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) [spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) [spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) [spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]  at com.example.hystrix.HelloServiceWithFallback$$EnhancerBySpringCGLIB$$680f4c58.hello(<generated>) [classes/:na]  at com.example.hystrix.Controller$RunnAlble.run(Controller.java:32) [classes/:na]  at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]​2019-07-17 17:27:17.587  INFO 3532 --- [eWithFallback-2] c.e.hystrix.HelloServiceWithFallback     : hello start!2019-07-17 17:27:17.587  INFO 3532 --- [eWithFallback-1] c.e.hystrix.HelloServiceWithFallback     : hello start!2019-07-17 17:27:18.576  INFO 3532 --- [ HystrixTimer-4] c.e.hystrix.HelloServiceWithFallback     : 这是造成服务降级的异常信息:ethan!!​com.netflix.hystrix.exception.HystrixTimeoutException: null  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.run(AbstractCommand.java:1142) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:37) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.tick(AbstractCommand.java:1159) [hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.util.HystrixTimer$1.run(HystrixTimer.java:99) [hystrix-core-1.5.18.jar:1.5.18]  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset(FutureTask.java) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]  at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]​2019-07-17 17:27:18.577  INFO 3532 --- [eWithFallback-1] c.e.hystrix.HelloServiceWithFallback     : hello start!2019-07-17 17:27:18.577  INFO 3532 --- [ HystrixTimer-2] c.e.hystrix.HelloServiceWithFallback     : 这是造成服务降级的异常信息:ethan!!​com.netflix.hystrix.exception.HystrixTimeoutException: null  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.run(AbstractCommand.java:1142) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:37) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.tick(AbstractCommand.java:1159) [hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.util.HystrixTimer$1.run(HystrixTimer.java:99) [hystrix-core-1.5.18.jar:1.5.18]  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset(FutureTask.java) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]  at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]​2019-07-17 17:27:18.579  INFO 3532 --- [ HystrixTimer-1] c.e.hystrix.HelloServiceWithFallback     : 这是造成服务降级的异常信息:ethan!!​com.netflix.hystrix.exception.HystrixTimeoutException: null  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.run(AbstractCommand.java:1142) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:37) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.tick(AbstractCommand.java:1159) [hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.util.HystrixTimer$1.run(HystrixTimer.java:99) [hystrix-core-1.5.18.jar:1.5.18]  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset(FutureTask.java) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]  at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]​2019-07-17 17:27:18.579  INFO 3532 --- [ HystrixTimer-3] c.e.hystrix.HelloServiceWithFallback     : 这是造成服务降级的异常信息:ethan!!​com.netflix.hystrix.exception.HystrixTimeoutException: null  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.run(AbstractCommand.java:1142) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:37) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.tick(AbstractCommand.java:1159) [hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.util.HystrixTimer$1.run(HystrixTimer.java:99) [hystrix-core-1.5.18.jar:1.5.18]  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset(FutureTask.java) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]  at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]​2019-07-17 17:27:18.580  INFO 3532 --- [ HystrixTimer-4] c.e.hystrix.HelloServiceWithFallback     : 这是造成服务降级的异常信息:ethan!!​com.netflix.hystrix.exception.HystrixTimeoutException: null  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.run(AbstractCommand.java:1142) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:37) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57) ~[hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.tick(AbstractCommand.java:1159) [hystrix-core-1.5.18.jar:1.5.18]  at com.netflix.hystrix.util.HystrixTimer$1.run(HystrixTimer.java:99) [hystrix-core-1.5.18.jar:1.5.18]  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308) [na:1.8.0_131]  at java.util.concurrent.FutureTask.runAndReset(FutureTask.java) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_131]  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]  at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]​​

我们看到“hello start!” 输出了三次,后面就没有输出了,而是直接输出了fallback 里的日志。证明实验成果。

本周关于hystrix我们就介绍到这里,如果不对之处欢迎指正交流!

https://mmbiz.qpic.cn/mmbiz_png/StSSauj2rMpmIK8ar9mNGKzwz57xsibVBmibra1bmQZnicgx5v5fyofianUWWibP2mwT3Yy2E0VkOEMaEFPILHaVHIA/640?wx_fmt=png

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值