One, the introduction
1. Serve avalanche
In a distributed project, with the continuous expansion of the project scale, the invocation between services becomes more and more complex and the links become longer and longer. Assume that the invocation relationship between services is as follows:
If service C responds slowly due to heavy request traffic or has problems, service B will continue to invoke service C, and its resources will be exhausted. As A result, service B will become unavailable, and service A will also be unavailable. When a service fails, the entire link fails. This phenomenon is called service avalanche. To avoid a service avalanche, service downgrades and service circuit breakers are usually used.
2. The service is degraded
So what is service degradation? To put it simply, when the request response is too slow or the downstream system is unavailable, some degradation logic is proactively invoked to return quickly and avoid a long wait. In fact, service circuit breaker is also a strategy of service degradation. Different from service degradation, service circuit breaker will directly abandon the invocation of the downstream system with slow response or unavailability, so as to ensure its availability, and resume the invocation when the target system improves. This circuit breaker mechanism is commonly usedBreaker mode:
- In the beginning
Closed
State, which is converted to when errors reach a thresholdOpen
- When the set is exceeded
reset timeout
, the state will change toHalf Open
, will attempt to call, once successful, will be converted againClosed
.
Second, the Hytrix
1. Hytrix profile
Hystrix controls the interaction between distributed services by adding delay tolerance and fault tolerance logic. This is done by isolating access points between services, stopping cascading failures between services, and providing fallback options. One thing to note is that Hytrix has gone into maintenance mode.
2. How Hytrix works
- Provides control protection against delays and failures of dependencies.
- Prevents cascading failures of distributed systems.
- Fail and recover quickly.
- Rewind and drop levels if possible.
- Near real-time monitoring, alerts and operational control.
3. Hytrix design Principles
- Prevents any single dependency from exhausting all user threads.
- Reduce load and fail quickly instead of queuing.
- Provide backup where feasible to protect users from failures.
- Use isolation techniques (such as partitions, swimlanes, and circuit breaker modes) to limit the impact of any dependency.
- Near real time indicators, monitoring and alerts ensure timely failure detection.
- Optimizes recovery time by propagating configuration changes with low latency, and supports real-time operational modification with dynamic property changes.
- Prevent entire dependent client execution from failing, not just network communication.
4. Hytrix implementation principle
- External calls are wrapped in command mode
HystrixCommand
orHystrixObservableCommand
Object and execute in a separate thread. - A small thread pool (or semaphore) is maintained for each dependency, and if it is full, requests to that dependency are rejected immediately rather than queued.
- Log failures (exceptions thrown by clients), timeouts, and thread rejections.
- Set the failure threshold. When the threshold is exceeded, turn on the short-circuit breaker and reject the request.
- The request fails, is rejected, times out, or is short-circuited.
- Monitor metrics and configuration changes in real time.
The flow chart of 5.
Hystrix’s journey map is as follows:
Specific execution process:
- structure
HystrixCommand
orHystrixObservableCommand
Object, the former is blocking, the latter is non-blocking; - perform
HystrixCommand
thequeue().get()
Method, orHystrixObservableCommand
thetoObserve()
Method to get the response, in factToObserve ()
Is a method that executes its parent class; - If caching is enabled and the request response is in cache, the cached response is returned;
- Check whether the circuit breaker is open, if so, adjust to 8, otherwise enter 5;
- Check if the thread pool and queue are full, if they are, go to 8;
- perform
run()
orconstruct()
Method that returns a single response orObservable
; - Record statistics to determine when to turn on the circuit breaker;
- Execute the configured fallback method;
- To return.
3. The Hystrix example
The example of this article is Spring Boot + Spring Cloud Feign + Spring Cloud Eureka.
3.1 Creating a Service Registry,
- Introducing dependencies:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Copy the code
- create
applicaiton.yml
The configuration file
Server: port: 7001 Spring: Application: name: Cloud-eureka-server: instance: appName: 127.0.0.1 Client: register-with-eureka: false # false: fetch-registry: false # false: service-url: defaultZone: http://127.0.0.1:7001/eurekaCopy the code
- Creating a startup class
@SpringBootApplication @EnableEurekaServer public class EurekaMain { public static void main(String[] args) { SpringApplication.run(EurekaMain.class, args); }}Copy the code
3.2 Creating a service provider
- Introduction of depend on
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Copy the code
- Creating a Configuration File
server: port: 8001 eureka: instance: instance-id: payment8001 client: register-with-eureka: true fetch-registry: True service - url: defaultZone: http://127.0.0.1:7001/eureka,Copy the code
- Create services and Controllers. This article is just for Hystrix, a simple example that does not involve database operations.
The controller layer
@RestController @RequestMapping("/payment") public class PaymentController { @Resource private IPaymentService paymentService; @RequestMapping("/success") public String successMethod() { return paymentService.successMethod(); } @RequestMapping("/fail") public String getTimeout(@RequestParam("id")Integer id){ return paymentService.failMethod(id); }}Copy the code
The service layer
public interface IPaymentService { String failMethod(Integer id); } @Service public class PaymentServiceImpl implements IPaymentService{ @Override @HystrixCommand(fallbackMethod="fallBackMethod", commandProperties = { @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", Value =" 50")}) public String failMethod(Integer id) {if (id < 0) {throw new RuntimeException("=====id cannot be negative ====="); } return "fail"; } public String fallBackMethod(Integer id) {return "fallBackMethod: "+ id; }}Copy the code
CircuitBreaker. Enabled: Enables the fuse. CircuitBreaker. RequestVolumeThreshold: request times threshold, is less than the threshold, even if other conditions meet won’t open circuit breaker; On the circuitBreaker. SleepWindowInMilliseconds: circuit breaker, to try to wait for time; The percentage of circuitBreaker. ErrorThresholdPercentage: wrong number. A more detailed configuration can be viewed in the HystrixCommandProperties class.
4. Create consumers
- Introduction of depend on
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Copy the code
- Creating a Configuration File
server: port: 80 eureka: client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://127.0.0.1:7001/eureka ribbon: ReadTimeout: 3000 ConnectTimeout: 3000 logging: level: Com. Fegin. Service. IPaymentFeign: open the debug # hystrix feign: hystrix: enabled: trueCopy the code
Creating a startup class
@enablecircuitbreaker public class Applicaiton {Hystrix @enablecircuitbreaker public class Applicaiton { public static void main(String[] args) { SpringApplication.run(Applicaiton.class, args); }}Copy the code
You can configure the global degrade method for the current class by creating the Controller and configuring the service degrade.
@RestController @RequestMapping("/cons") @DefaultProperties(defaultFallback = "global_fialMethod") public class ConsumerController { @Resource IPaymentFeign paymentFeign; @GetMapping("/fail") @HystrixCommand public String get(){ return paymentFeign.failMethod(); } public String global_fialMethod() { return "global_fialMethod"; }}Copy the code
The other configuration, because of the integration with OpenFeign, which supports Hystrix itself, can implement the interface directly, and when the service invocation fails, go native to implement the class, making the coding more elegant.
@Component @FeignClient(value = "CLOUD-PAYMENT-HYSTRIX",fallback = PaymentImpl.class) public interface IPaymentFeign { @RequestMapping("/payment/failMethod") String failMethod(); } @Service public class PaymentImpl implements IPaymentFeign{ @Override public String failMethod() { return "local failMethod"; }}Copy the code
This article is my study in the summary and notes, if there is insufficient, I hope all the gods can pay.
reference
www.cnblogs.com/aiqiqi/p/11… Github.com/Netflix/Hys…