Simple application and understanding of spring cloud hystrix

preface

hystrix is a well-known service degradation and fusing component launched by Netflix

The main principle of hystrix design is to solve the cascading failure of associated services caused by network uncertainty in distributed environment.

For example, service A calls service B, service B calls Service C, and Service C calls service D. due to the failure of service D, service C cannot get A response when calling service D. for example, the timeout is returned after the response time reaches 30 seconds.

If 500 requests call service A in these 30 seconds, due to the failure of service D, 500 threads of services A, B and C will be suspended. At this time, 500 threads may be the limit of services A, B and C, which will lead to inaccessibility when other requests call normal requests of services A, B and C, and finally lead to paralysis of services A, B and C.

hystrix is to solve the cascading failure of the above service dependency calls

hystrix usage

Add dependencies to a spring cloud project

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

Annotate the startup class @ enablercircuitbreaker

Now let's write a D service, that is, the method of D service will delay for 2 seconds and then return

@RestController
public class HystrixController33 {

	// Start the Hystrix for this method. If it fails, enter the fallbackMethod method method of the current class,
	// The parameters of fallbackMethod must be consistent with the current one, and Throwable parameter can be added
    @HystrixCommand(fallbackMethod = "fallbackMethod")
    @GetMapping("/hystrixTimeOut")
    public String hystrixTimeOut() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       
        return "success";
    }

    
    public String fallbackMethod(Throwable e) {
        System.out.println("error:"+e.toString());
        return "get into fallbackMethod";
    }

}

At this time, if a C service calls the hystrixTimeOut method of D service through spring's RestTemplate, the hystrixTimeOut method of D service will enter the fallbackMethod method and return the failure information. The reason is that the default timeout of hystrix is 1 second, that is, when the hystrixTimeOut is blocked for two seconds, it will enter the fast failure mode if it exceeds the default timeout of 1 second. Hystrix solves the cascading failure of services by means of service degradation (rapid failure)

So far, we have understood the core idea of hystrix

Of course, hystrix also has a wealth of degradation strategies, supporting fuse, timeout, current limit, failure threshold and other strategies

1. Timeout degradation
application.properties configure the following configuration

# The timeout of ribbon is mainly to avoid that the load balancing timeout of ribbon will affect the timeout of hystrix when RestTemplate is used
ribbon.ReadTimeout=10000
ribbon.ConnectTimeout=10000
# Enable timeout degradation. The default value is true
hystrix.command.default.execution.timeout.enabled=true
# Set the timeout to 5 seconds, and the default is 1 second. This configuration must be changed
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000

At this time, when C calls D, the method will not be degraded because the blocking time of 2 seconds is less than 5 seconds

2. Current limiting degradation

# hystrix current limiting
# Thread pool flow limiting mode is adopted
hystrix.command.default.execution.isolation.strategy=THREAD
# The number of core threads of thread flow restriction must be modified. If it is not modified, the default concurrency is only 10. If it exceeds 10, the flow restriction will be degraded
hystrix.threadpool.default.coreSize=100
# The maximum number of queues in BlockingQueue. The default value is - 1 (- the following queueSizeRejectionThreshold will be invalid when configured with 1)
hystrix.threadpool.default.maxQueueSize=300
# Even if maxQueueSize is not reached, the request will be rejected when the value of queueSizeRejectionThreshold is reached. The default value is 5
# It is best to configure maxQueueSize and queueSizeRejectionThreshold to be consistent. If both use the default, the maximum concurrency is coreSize. If it exceeds, it will be rejected
hystrix.threadpool.default.queueSizeRejectionThreshold=300

Configure current limiting degradation, adopt THREAD mode for current limiting, and configure SEMAPHORE current limiting,
Configure the maximum number of core threads and the queue length. Under the above configuration, only the hystrixTimeOut of service D has 100 + 300 concurrent requests coming in at the same time. Requests exceeding the threshold will be degraded. In this way, resources are well protected to avoid resource depletion caused by excessive concurrency

If you want to use SEMAPHORE, configure

# Use semaphore mode to set concurrency
hystrix.command.default.execution.isolation.strategy=SEMAPHORE
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=200
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=200

The above configuration is degraded when the threshold reaches 200

3. Failure threshold degradation
The default failure threshold rule of hystrix is: by default, there are more than 20 requests in 10 seconds, and the failure rate reaches 50%, that is, the current method enters degradation. The failure rate threshold can be configured

# Configuration is 60%
circuitBreaker.errorThresholdPercentage = 60

When the method is degraded, it will accept the request again after 5 seconds by default. At this time, some requests will be allowed to pass. If the requests are healthy (response time < 250ms), the health of the request will be restored (fuse will be cancelled). If they are not healthy, fuse will continue.

feign interface integrated with hystrix

feign interface can integrate hystrix and be configured as

@FeignClient(name="order", fallback = OrderFallback.class)
public interface OrderInterface {
    @RequestMapping(value = "/test", method = GET)
    String test(@RequestParam("name") String name);
}
@Component
public class OrderFallback implements OrderInterface {
    @Override
    public String test(String name) {
        return "The request failed";
    }
}

When we open the above configuration file application After some hystrix configurations of properties, calling the feign interface OrderInterface can use hystrix configuration by default, so there is no need to configure the method annotation @HystrixCommand. When we do not use the feign interface, we need to use @ HystrixCommand(fallbackMethod = "fallbackMethod") for a method if we want to start the degradation test

The fallbackMethod of HystrixCommand can be configured as a public fallback method of a class. The configuration is as follows, using @ DefaultProperties

@DefaultProperties(defaultFallback = "fallbackTest")
@RestController
public class HystrixController2 {


    @HystrixCommand
    @ApiOperation("Test fusing timeout")
    @GetMapping("/testHystrix222")
    public String testHystrix(@RequestParam("num") int num) {

        if(true) {
            throw new BizException(501,"2222222222 abnormal");
        }

        return null;
    }

    /**
     * The parameters must be the same, and the Throwable parameter can be added
     */
    public String fallbackTest(Throwable e) {
        System.out.println("error:"+e.toString());
        return "get into fallbackMethod";
    }

}

summary

1. The core idea of hystrix is to solve the cascading failure of multiple service dependent calls

2. If the request chain between multiple services is not invoked, it is generally unnecessary to configure hystrix. If the method involves remote invocation, it is necessary to consider using the degradation strategy to avoid the service paralysis caused by the timeout of remote invocation

Tags: Java Distribution Hystrix

Posted by inerte on Tue, 24 May 2022 18:30:07 +0300