1. Why use Hystrix
When calling between multiple microservices, assume that microservice A calls microservice B and microservice C, and microservice B and microservice C are calling other microservices. This is the so-called “fan-out”. If the call response time of a certain microservice on the fan-out link is too long or is unavailable, the call to microservice A will occupy more and more system resources, causing the system to crash. This is the so-called “< strong>Avalanche Effect”.
2. Overview of Hystrix
The occurrence of this “avalanche effect” is definitely terrible. In a distributed system, we cannot guarantee that a certain service will not have problems, and Hystrix can solve it.
Hystrix is an open source library used to handle latency and fault tolerance in distributed systems. In distributed systems, many services inevitably fail to call, such as timeouts, exceptions, etc. Hystrix can ensure that when a service fails, It will not cause the failure of the overall service and avoid cascading failures to improve the resilience of the distributed system.
3.Usage of Hystrix
3.1 Use hystrix service breaker in the requested interface class
1. Add dependencies
order-service
<!-- Introducing hystrix integrated with spring cloud --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.10.RELEASE</version> </dependency>
2. Activate hystrix
@EnableHystrix public class OrderServiceApplication {<!-- -->
3. Downgrade processing
(1) Add a downgrade method in OrderController
/** * Downgrade method * The return value and method parameters are consistent with the method that needs to be protected */ public Product orderFallBack(Long id){ Product product = new Product(); product.setProductName("Trigger downgrade method"); return product; }
(2) Use @HystrixCommand
configuration on methods that need to be protected
@HystrixCommand(fallbackMethod = "orderFallBack") @GetMapping(value = "/buy/{id}") public Product findById(@PathVariable Long id) { return productFeignClient.findById(id);
(3) Simulate network delay (in product-service)
try { Thread.sleep(2000l);//Simulate request network delay } catch (InterruptedException e) { throw new RuntimeException(e); }
(4) Hystrix configuration (in application.yml of order-service)
hystrix: command: default: execution: isolation: strategy: ExecutionIsolationStrategy.SEMAPHORE #Semaphore isolation #strategy: # ExecutionIsolationStrategy.THREAD thread pool isolation thread: timeoutInMilliseconds: 2000 #The default connection timeout is 1 second. If no data is returned within 1 second, the downgrade logic will be automatically triggered. circuitBreaker: requestVolumeThreshold: 5 #Minimum number of requests to trigger circuit breaker, default 20/10 seconds sleepWindowInMilliseconds: 10000 #How many seconds after the fuse is broken to try the request. Default 5 is the time to open the state. errorThresholdPercentage: 50 #Minimum proportion of failed requests that trigger circuit breaker, default 50%
(5) Test
Start eureka, product, and order services http://localhost:9002/order/buy/1
Because the simulated network delay is 2s and the database request will be greater than 2s, the downgrade method will be triggered. Now change the thread timeout to 6s and see the results.
Normal access to data
4. Unified downgrade method
If you write a downgrade method for each method, it will be very troublesome when there are many methods. You can specify the downgrade method uniformly.
(1) Modify the OrderController class and add a unified downgrade method
/** * Specify a unified downgrade method * Note that the method has no parameters */ public Product defaultFallBack(){ Product product = new Product(); product.setProductName("Trigger unified downgrade method"); return product; }
(2) Add the @DefaultProperties
annotation above the OrderController class
@DefaultProperties(defaultFallback = "defaultFallBack") public class OrderController {<!-- -->
(3) Modify the @HystrixCommand
annotation above the findById method and change @HystrixCommand(fallbackMethod = “orderFallBack”) to @HystrixCommand
(4) 6s>2s
(5) Test
3.2 Feign combines hystrix service circuit breaker
1. Copy service
Copy order-service to get order-service-feign_hystrix (Note: There will be problems if you copy directly in idea. There will be no problems if you copy it in the file explorer.)
2. Open hystrix and related configurations in feign
Modify order-service-feign_hystrix service application.yml to enable hystrix in Fegin
# Enable hystrix fusing in feign Feign: circuitbreaker: enabled: true
Modify port number and service name
server: port: 9003 spring: application: name: service-order-feign_hustrix
hystrix settings
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 2000 #The default connection timeout is 1 second. If no data is returned within 1 second, the downgrade logic will be automatically triggered. circuitBreaker: enabled: true requestVolumeThreshold: 5 errorThresholdPercentage: 10 sleepWindowInMilliseconds: 10000
3. Implement downgrade logic in the interface implementation class
Write the interface implementation class and write the circuit breaker and downgrade method.
package org.example.order.feign; import org.example.order.entity.Product; import org.springframework.stereotype.Component; @Component public class ProductFeginClientCallBack implements ProductFeignClient{ /** * Downgrade method */ @Override public Product findById(Long id) { Product product = new Product(); product.setProductName("Trigger Feign circuit breaker downgrade method"); return product; } }
4. Interface annotation declares downgraded class
Modify ProductFeignClient interface
In @FeignClient
add the class where the method using fallback is located fallback = ProductFeginClientCallBack.class
@FeignClient(name = "service-product", fallback = ProductFeginClientCallBack.class) public interface ProductFeignClient { /** * Configure the microservice interface that needs to be called * @return */ @RequestMapping(value = "/product/{id}", method = RequestMethod.GET) Product findById(@PathVariable("id") Long id); }
5. Comment or delete the previous Hystrix-related code
Comment or delete the @EnableHystrix
annotation of the startup class
6. Test
Start eureka, product, order (9003) service http://localhost:9003/order/buy/1