Netflix / Hystrix

Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
24.07k stars 4.7k forks source link

【BUG】use HystrixTimer execute fallback will cause fallback execute twice? #1588

Open Yaccc opened 7 years ago

Yaccc commented 7 years ago

Because hystrixtimer and workerThread do not synchronize, this can cause this problem!

when run() method throw a exception,workerThread will execute the fallback() method.

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import rx.Observable;
import rx.Subscriber;
import java.io.IOException;

public class HystrixUse extends HystrixCommand<String> {
   public static ThreadLocal<String> threadLocal=new ThreadLocal<>();
    private String name;

    public HystrixUse(String name) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("Semaphore Echo"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("Echo"))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                        .withExecutionIsolationSemaphoreMaxConcurrentRequests(2).withExecutionIsolationThreadTimeoutInMilliseconds(2000)
                .withExecutionIsolationThreadInterruptOnTimeout(true).withFallbackIsolationSemaphoreMaxConcurrentRequests(1)));
        this.name = name;

    }

    @Override
    protected String run() throws Exception {

        int [] a=new int[5];
        System.out.println("execute run");
        //cause  exception
        int i = a[6];
        return "hello" + name;
    }

    @Override
    protected String getFallback() {
        System.out.println("execute -fallback"+Thread.currentThread());

        return "fallback";
    }

    public static void main(String[] args) {

        HystrixUse hystrixUse=new HystrixUse("nn");
        Observable<String> stringObservable = hystrixUse.toObservable();
        stringObservable.subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                System.out.println("completed");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println(e);
            }

            @Override
            public void onNext(String s) {
                System.out.println(s);
            }
        });

        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

when execute run,use a breakpoint hang the workerThread on HystrixCommond object image ,then wait time is timeout.the HystrixTimer will execute fallback.the result is as follows

execute run
execute -fallbackThread[hystrix-Semaphore Echo-1,5,main]
execute -fallbackThread[HystrixTimer-1,5,main]
fallback
completed

fallback method execute twice, this is a bug? or other reasons

my version is 1.3.16

mattrjacobs commented 7 years ago

Executing the fallback twice is definitely a bug. Are you able to upgrade to the latest Hystrix (or even something in the 1.4.x series) and see if the bug occurs there?

Yaccc commented 7 years ago

@mattrjacobs I can't find pull request in CHANGELOG. can you give me a bugfixed version? thank you very much!!

mattrjacobs commented 7 years ago

I'm not sure what you're looking for. Many things have changed since 1.3.16 - that's at least 3 years old. If you have a reliable way of reproducing your issue in 1.3.16, it would be great to know if you an repro it in a newer version.

Yaccc commented 7 years ago

i'm a member of Base component team , Many business R & D teams use our components,I have to make sure a hystrix version is available.In this case, I can only test each version.

Thank you for your reply!