Preface:
1. Introduction to Hystrix
In a distributed system, many dependencies inevitably fail to invoke, such as timeouts, exceptions, and so on. How to ensure that the whole service fails when a dependency fails is what Hystrix needs to do. Hystrix provides functions such as fuse, isolation, Fallback, cache, monitoring and so on. It can ensure that the system is still available when one or more dependencies have problems at the same time.
2. Why use Hystrix
In distributed system architecture, communication between multiple systems is usually carried out through remote RPC calls, that is, system A calls system B services, and system B calls system C services. When tail application C fails and system B fails to downgrade, it may cause B, or even system A to be paralyzed. This phenomenon is called avalanche phenomenon. Therefore, in the design of the system, we should use a certain downgrading strategy to ensure that when the service provider service is not available, the service caller can switch to the downgraded policy for execution.
Actual combat:
1. New service consumers:
(1) Adding dependencies
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xm.cloud</groupId> <artifactId>cl_hello_consumer_hy</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>cl_hello_consumer_hy</name> <description>This is a Web about springcloud</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
(2) Modify configuration
eureka.client.service-url.defaultZone=http://127.0.0.1:7001/eureka/ eureka.client.register-with-eureka=false feign.hystrix.enabled=true
(3) Opening Notes
package com.xm.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableDiscoveryClient @EnableFeignClients @SpringBootApplication public class ClHelloConsumerHyApplication { public static void main(String[] args) { SpringApplication.run(ClHelloConsumerHyApplication.class, args); } }
(4) Configuration of Fuse Callback Plant
package com.xm.cloud.fallback; import org.springframework.stereotype.Component; import com.xm.cloud.service.HelloService; import feign.hystrix.FallbackFactory; @Component public class HelloServiceFallbackFactory implements FallbackFactory<HelloService> { @Override public HelloService create(Throwable cause) { return new HelloService() { @Override public String sayHello() { return "HelloService Abnormal!"; } }; } }
(5) New Service
package com.xm.cloud.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import com.xm.cloud.fallback.HelloServiceFallbackFactory; @FeignClient(value="CL-HELLO-PRODUCER",fallbackFactory=HelloServiceFallbackFactory.class) public interface HelloService { @GetMapping("/hello") public String sayHello(); }
(6) New Controller
package com.xm.cloud.controller; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.xm.cloud.service.HelloService; @RestController public class HelloController { @Autowired private HelloService helloService; @GetMapping("/hello") public List<String> sayHello() { List<String> list = new ArrayList<String>(); for(int i=0;i<10;i++) { list.add(helloService.sayHello()); } return list; } }
2. New service providers:
(1) Adding dependencies
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xm.cloud</groupId> <artifactId>cl_hello_producer_hy</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>cl_hello_producer_hy</name> <description>This is a Web about springcloud</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
(2) Modify configuration
server.port=8001 spring.application.name=cl-hello-producer eureka.client.service-url.defaultZone=http://127.0.0.1:7001/eureka/
(3) Opening Notes
package com.xm.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @EnableCircuitBreaker @SpringBootApplication public class ClHelloProducerHyApplication { public static void main(String[] args) { SpringApplication.run(ClHelloProducerHyApplication.class, args); } }
(4) New Controller
package com.xm.cloud.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @RestController public class HelloController { @GetMapping("/hello") @HystrixCommand public String sayHello() { if(Math.random()>0.5) { throw new RuntimeException(); } else { return "Hello spring cloud!"; } } }
3. test
Run: localhost:8080/hello
0 | "HelloService exception! " |
---|---|
1 | "Hello spring cloud!" |
2 | "HelloService exception! " |
3 | "Hello spring cloud!" |
4 | "Hello spring cloud!" |
5 | "Hello spring cloud!" |
6 | "Hello spring cloud!" |
7 | "Hello spring cloud!" |
8 | "HelloService exception! " |
9 | "Hello spring cloud!" |