Introduction of depend on

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
Copy the code

I’m going to annotate the main function with @enablehystrix and it doesn’t seem to be a problem if I don’t add the above comments to the test. We’re going to start with HystrixCommand inheritance so that we can see the details a little bit more visually

First use: use the HystrixCommand inheritance form

Public class MyCommand extends HystrixCommand<Integer> {@autoWired private Dome Dome; // constructor protected MyCommand(Dome Dome) {// Dome is the corresponding class, Super queryByOrderId is one of the specific method (Setter. WithGroupKey (HystrixCommandGroupKey. Factory. AsKey (" dome ")) .andCommandKey(HystrixCommandKey.Factory.asKey("queryByOrderId")) AndCommandPropertiesDefaults (HystrixCommandProperties. Setter (.) withCircuitBreakerRequestVolumeThreshold at least ten (10) / / requests, Fuse to the error rate is calculated. WithCircuitBreakerSleepWindowInMilliseconds (5000) / / fuse interrupt request after 5 seconds will enter a state of half open, part of the flow past a retry . WithCircuitBreakerErrorThresholdPercentage (50) / / error rate up to 50 open fuse protection. WithExecutionTimeoutEnabled (true)) .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties .Setter().withCoreSize(10))); this.dome = dome; } @Override protected Integer run() throws Exception { return null; } @Override protected Integer getFallback() { return -1; }Copy the code

Began to run

public void testQueryByOrderIdCommand() {
        Integer r = new MyCommand(dome).execute();
}
Copy the code

There are several ways to do this, as explained below

execute()

Execution of run() in synchronous blocking supports receiving only one value object. Hystrix takes a thread from the thread pool to execute run() and waits for the return value.

queue()

Execute run() asynchronously, non-blocking, and accept only one value object. Calling queue() returns a Future object directly. The return result of run() can be obtained with future.get (), but future.get () is blocked. On success, future.get () returns a single return value. Future.get() throws an exception if the fallback is not overwritten when execution fails.

observe()

Run ()/construct() is executed before event registration, which supports receiving multiple value objects, depending on the emitter. Call observe() returns a hot Observable, that is, call observe() automatically triggers run()/construct() regardless of whether a subscriber exists. If HystrixCommand is inherited, Hystrix takes a thread from the thread pool and executes run() in a non-blocking manner; If HystrixObservableCommand is inherited, construct() is executed with the call thread blocking.

Observe () How to use:
Observe () returns an Observable. 2. Subscribe () is called to register the Observable eventCopy the code

toObservable()

Run ()/construct() is executed after event registration, which supports receiving multiple value objects, depending on the emitter. Calling toObservable() returns a Cold Observable. That is, calling toObservable() does not trigger run()/construct() immediately, but only when a subscriber subscribes to an Observable. If HystrixCommand is inherited, Hystrix takes a thread from the thread pool and executes run() in a non-blocking manner. The calling thread does not have to wait for run(); If the HystrixObservableCommand is inherited, construct() is blocked by the calling thread, which waits for construct() to finish before proceeding.

ToObservable ()

Observe () returns an Observable. 2. Subscribe () is invoked to register eventsCopy the code

Note that HystrixCommand also supports toObservable() and observe(), but even when HystrixCommand is converted toObservable, it can only emit one value object. Only HystrixObservableCommand supports firing multiple value objects. The figure below shows several ways to connect

Execute () actually calls queue().get() queue() actually calls toObservable().toblocking ().toFuture() observe() Actually calls toObservable() to get a cold Observable, and then create a ReplaySubject object to subscribe to an Observable, converting the source Observable into a Hot Observable. Therefore calling observe() automatically triggers the execution of run()/construct().

  • The above inheritance method can be very clear to see the details, but relatively tedious code typing, generally can use the official annotations to use, the following is the second method

Method 2: Run @hystrixCommand to configure related information

@SneakyThrows @GetMapping("/getOther") @HystrixCommand(fallbackMethod = "fallback", ThreadPoolKey =" getTodayStatisticB", threadPoolProperties = {@hystrixProperty (name="coreSize",value =" 1"), @hystrixProperty (name="maxQueueSize",value="100"); CommandProperties = {// Similar to kv // here this parameter means the fuse timeout is 2s, Haven't said how long did it take to end for fusing @ HystrixProperty (name = "execution. The isolation. Thread. TimeoutInMilliseconds," value = "2000"), / / when faced with failure, Open a window of 11 s @ HystrixProperty (name = "metrics. RollingStats. TimeInMilliseconds," value = "11000"), / / the minimum number of requests @ HystrixProperty (name = "circuitBreaker. RequestVolumeThreshold", value = "3"), / / number of failure accounted for 50% of the request @ HystrixProperty (name = "circuitBreaker. ErrorThresholdPercentage", value = "50"), / / trip after active window configuration Here is configured with 10 s @ HystrixProperty (name = "circuitBreaker. SleepWindowInMilliseconds", value = "10000")}) public String getOther(@requestParam (Required = false) String userId){// Suspend thread.sleep (2000); System.out.println(" thread.currentThread ().getName() "); String res = restTemplate.getForObject("http://CLIENT2-SERVICE/client2/get",String.class); return res; }Copy the code

Using Configuration

CommandProperties configuration details fusing execution. The isolation. Thread. TimeoutInMilliseconds for timeout After the metrics. RollingStats. TimeInMilliseconds when faced with failure, Open a certain time window (see sliding window current-limiting) circuitBreaker. RequestVolumeThreshold minimum number of requests circuitBreaker, errorThresholdPercentage failure rate CircuitBreaker. SleepWindowInMilliseconds trip after sliding window of timeCopy the code

test

Following the configuration shown in the code above, we started testing using Thread.sleep(2000); As shown in the code above, we set the failure ratio as 50%. The thread written in our code is suspended for 2 seconds. Using postman call, we can find that the first two times enter the fuse, the time is about 2 seconds

The third time to enter the fuse is

It can be found that we have entered the failure window and wait 11 seconds to request again and then start to judge again. It can be seen that the time of the failure sliding window configured previously is 11s

Method 3: We can also use the form of YML configuration