Curcuit Breaker mode
In distributed environments, especially in distributed systems with microservice structures, it is very common for one software system to call another remote system. The callee of this remote call may be another process, or another host across the network. The biggest difference between this remote call and the internal call of the process is that the remote call may fail or hang without any response until the timeout. Even worse, if multiple callers call the same pending service, it is very likely that the timeout wait of a service will quickly spread to the entire distributed system, causing a chain reaction, and thus consume a large amount of resources of the entire distributed system. It may eventually lead to system paralysis.
The Circuit Breaker mode is to prevent disasters caused by such a waterfall-like chain reaction in distributed systems.
Once a certain electrical appliance has problems, the fuse of the circuit will blow to prevent disaster. Circuit breakers are similar to circuit fuses. The implementation idea is very simple. They can encapsulate remote services that need protection and monitor the number of failures internally. Once the number of failures reaches a certain threshold, all subsequent calls to the service will directly return the error to the caller after the circuit breaker intercepts, and will not continue to call the service that has already had problems, thereby achieving the purpose of protecting the caller. The entire system will not experience a waterfall chain reaction caused by timeout.
1. Basic mode
The above figure is the structure of a circuit breaker (Curcuit Breaker), which has two basic states (close and open) and a basic trip action:
In the close state, the client requests the service to the supplier directly through the circuit breaker without any obstacles. The return value of the supplier is directly returned to the client by the circuit breaker.
In the open state, after the client initiates a service request to the supplier, the circuit breaker will not transfer the request to the supplier, but will directly return the client, and the path between the client and supplier is broken.
trip: In the close state, if the supplier continues to time out and error, after reaching the specified threshold, trip will occur in the circuit breaker, and then the circuit breaker state will enter open from close.
2. Extended mode
In the basic circuit breaker mode, it ensures that the circuit breaker will not be called when the circuit breaker is in the open state, but we also need additional measures to reset the circuit breaker after the supplyer restores the service. One feasible way is to regularly detect whether the supplier's service is restored, and once it is restored, the status is set to close. The state of the circuit breaker retry is half-open.
3. Use occasions for circuit breakers:
A supplier is generally very stable. If once a failure occurs, the inspection and recovery time takes a long time and cannot be quickly repaired in a short time, then this service is more suitable for using the circuit breaker mode. Otherwise, it is likely to lead to a ping-pong effect.
3. Circuit breaker is not suitable for occasions:
To prevent an application from attempting to invoke a remote service or access a shared resource, this pattern may not be suitable if the operation is highly likely to fail.
For processing applications accessing local dedicated resources, such as data structures within memory. In this environment, it is not usually suitable, and using a circuit breaker will only increase system overhead.
The following is a direct introduction to how to use Spring Cloud's circuit breaker.
SpringCloud Netflix implements the name of the circuit breaker library called Hystrix. Under the microservice architecture, there are usually multiple levels of service calls. The following is a schematic diagram of the browser accessing the backend microservices through API under the microservice architecture:
The failure of a microservice timeout may lead to a waterfall chain reaction. In the figure below, Hystrix prevents this from happening through an autonomous feedback circuit breaker.
Service B in the figure fails for some reason and becomes unavailable. All calls to Service B will time out. When the call to B fails to reach a specific threshold (20 failures occur within 5 seconds are the default value defined by Hystrix), the link will be in the open state, and then all calls to service B will not be executed, instead a Fallback message indicating the link open provided by the circuit breaker. Hystrix provides a corresponding mechanism that allows developers to define this Fallbak message.
Open's link blocks a waterfall error, allowing flooded or wrong services to have time to fix. This fallback can be another Hystrix protected call, static data, or legal null value. Fallbacks can form a chain structure, so the first fallback that calls other business services at the bottom to return static data.
Next, let’s get to the point, adding a circuit breaker to the previous two HELLO WORLD service clusters to prevent one of the Hello world from slacking, causing the system to fail to chain timeout.
1. Add the hystrix library to support circuit breakers in the pom.xml of maven project (Ribbon or Feign project introduced in the previous chapter)
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId></dependency>
2. Use circuit breakers in Ribbon applications
1). Add @EnableCircuitBreaker annotation on Spring Boot startup class
@SpringBootApplication@EnableDiscoveryClient@EnableCircuitBreakerpublic class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run(ServiceRibbonApplication.class, args); }2). Annotate the method of accessing services with @HystrixCommand annotation
@Servicepublic class HelloService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "serviceFailure") public String getHelloContent() { return restTemplate.getForObject("http://SERVICE-HELLOWORLD/",String.class); } public String serviceFailure() { return "hello world service is not available !"; }}The @HystrixCommand annotation defines a circuit breaker that encapsulates the getHelloContant() method. When the SERVICE-HELLOWORLD it accesses fails to reach the threshold, SERVICE-HELLOWORLD will no longer be called. Instead, it returns the method serviceFailure() defined by fallbackMethod. There are two points that need to be paid special attention to when defining the fallbackMethod method defined by the @HystrixCommand annotation:
First, the return value and parameter type of fallbackMethod need to be exactly the same as the method annotated by @HystrixCommand. Otherwise, an exception will be thrown at runtime. For example, in this example, the return value of serviceFailure() and the return value of getHelloContant() method are both Strings.
Second, when the underlying service fails, fallbackMethod does not replace the entire method annotated by @HystrixCommand (getHelloContant in this example), but only the specific service accessed through restTemplate. You can see from the system output that even if it fails, there will still be "call SERVICE-HELLOWORLD" in the console output.
Start the eureka service, start only two Helloworld services, and then interrupt one of them (simulate one of the microservices suspended), visit http://localhost:8901/ and then refresh, due to load balancing, you can see the following two pages appear alternately. You can see that the second pending service is replaced by the error handling method defined in Ribbon.
4. Use circuit breakers in Feign applications
1). Feign already supports circuit breakers, so you don’t need to think about Ribbon’s method, add extra annotations to the Spring Boot startup class.
2). Add fallback class with @FeignClient annotation, which must implement the interface modified by @FeignClient.
@FeignClient(name = "SERVICE-HELLOWORLD", fallback = HelloWorldServiceFailure.class) public interface HelloWorldService { @RequestMapping(value = "/", method = RequestMethod.GET) public String saysHello(); }3). To create the HelloWorldServiceFailure class, you must implement the HelloWorldService interface modified by @FeignClient. Note that you add @Component or @Service annotation to generate a bean in the Spring container.
@Componentpublic class HelloWorldServiceFailure implements HelloWorldService { @Override public String saysHello() { System.out.println("hello world service is not available !"); return "hello world service is not available !"; }}4). In the Brixton versions before Spring Cloud, Feign automatically activated the circuit breaker by default, but the recent Dalston version has changed the default configuration to prohibit.
For reasons, please refer to: https://github.com/spring-cloud/spring-cloud-netflix/issues/1277. Pay attention to this point. Therefore, to use circuit breakers in Feign, you must add the following configuration in application.yml:
feign: hystrix: enabled: true
5). Launch the Feign application and visit http://localhost:8902/hello to see the same effect as Ribbon.
Reference: http://projects.spring.io/spring-cloud/spring-cloud.html#_circuit_breaker_hystrix_clients
http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign-hystrix
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.