demo code address https://github.com/qinkuan/springcloudtest
Catalog
demo code addresshttps://github.com/qinkuan/springcloudtest
Common components and roles in SpringCloud
Maven Environment Preliminary Setup
Apply Exposure Running Information
What is SpringCloud
SpringCloud is a collective term for a series of components used to build reliable micro-service applications in the Spring ecosystem. The functions provided include, but are not limited to, service governance, interface Http calls, load balancing, service degradation and breakdown, data health, gateways, configuration centers, message bus, etc.
Common components and roles in SpringCloud
-
Eureka: Cloud Service Discovery, a REST-based service for locating services for cloud mid-tier service discovery and failover.
-
OpenFeign:Feign is a declarative, templated HTTP client
-
Ribbon: Provides cloud load balancing with a variety of load balancing strategies for use with service discovery and circuit breakers
-
Hystrix: Fuser, Fault Tolerance Management Tool, designed to control the nodes of services and third-party libraries through a fuse mechanism to provide greater fault tolerance for delays and failures
-
SpringCloudConfig: Configuration Management Toolkit that allows you to place configurations on remote servers, centralize cluster configuration management, and currently supports local storage, Git, and Subversion
-
Zuul: Zuul is a framework for providing dynamic routing, monitoring, resilience, security, and other edge services on cloud platforms. Zuul is equivalent to the front door to all requests on the back end of a Web site for devices and Netflix streaming applications
-
Spring CloudBus: Event, message bus, used to propagate state changes in clusters (for example, configuration change events), which can be jointly deployed with Spring Cloud Config for hot deployment.
-
Consul: Encapsulates the Consul operation, a service discovery and configuration tool that seamlessly integrates with the Docker container
Maven Environment Preliminary Setup
Dependency Introduction of Main Project
<?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> <!--Introduce Springboot--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> </parent> <groupId>org.example</groupId> <artifactId>springcloudtest</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <!--Manage subprojects--> <modules> <module>provider-8100</module> <module>provider-8101</module> <module>provider-8102</module> <module>consumer-8200</module> <module>consumer-8201</module> <module>eureka-server-8300</module> <module>eureka-server-8301</module> <module>springcloud-hystrix-dashboard-8400</module> </modules> <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>Hoxton.RELEASE</spring-cloud.version> <log4j.version>1.2.17</log4j.version> </properties> <dependencyManagement> <!--Yes springcloud Unified management of versions of--> <dependencies> <!--spring cloud Hoxton.SR1--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!--spring cloud Alibaba--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> </plugins> </build> </project>
Use of Eruaka
Maven Introduction
<!--eureka-server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!--spring boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
configuration file
server: port: 8300 spring: application: name: springcloud-eureka-server-8300 eureka: instance: ## You need to modify the DNS here to map this domain name to your local machine. Instead of using localhost directly, an instance can only be used by one domain name hostname: server1.com client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/,http://server2.com:8301/eureka/
Start two Eureka server instances
@SpringBootApplication @EnableEurekaServer public class EurekaServer8300 { public static void main(String[] args){ SpringApplication.run(EurekaServer8300.class, args); } }
<?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"> <parent> <artifactId>springcloudtest</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>provider-8100</artifactId> <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.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
spring: application: name: provider server: port: 8100 eureka: instance: instance-id: ${spring.application.name}:${server.port} client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://server1.com:8300/eureka/,http://server2.com:8301/eureka/ #Eureka address
@SpringBootApplication @EnableDiscoveryClient public class Provider { public static void main(String[] args) { SpringApplication.run(Provider.class, args); } }
So we've finished, registering the eureka server-side cluster with the client
Use of Openfeign
OpenFeign is a declarative, templated client that integrates Ribbon, and we first register three provider s into EruekaServer
Next, we start a client that connects to OpenFeign: Consumer
Join maven dependency
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
Add Load Balancing Comment to RestTemplate
@Configuration public class RestConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
Defining an http client using @FeignClient
@Component @FeignClient(name = "provider", fallback = ProductFallbackServieImpl.class) public interface ProductService { @GetMapping("/product/provider/serviceInfo") String getServiceInfo(); @GetMapping("/product/provider" + "/getById?id={id}") String selectById(@PathVariable("id") Long id); }
Define Failure Return Class for Service Demotion
@Component public class ProductFallbackServieImpl implements ProductService{ @Override public String getServiceInfo() { return "Server has drifted off"; } @Override public String selectById(Long id) { return "Server has drifted off"; } }
Finally, add the @EnableFeignClients annotation to the startup class and start
Access provider interface returns port information
As you can see from the diagram, the consumer requests service providers on different ports
Use of Hystrix
Introducing maven dependencies
<!--hystrix --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
service degradation
In microservices, to avoid downstream service anomalies, resulting in upstream service anomalies or resource occupancy, special treatment is usually taken to ensure that
The normal operation of the service, such as when we invoke an exception to the inventory service in an order service, usually does not return the exception directly to the user, but uses a downgrade function instead of the original function, such as the exception handling function used in the previous block of content.
Add to Profile
feign: hystrix: enabled: true # fegin shuts down hystrix service by default
And add the @EnableCircuitBreaker annotation to the startup class
We visited an exception interface of the provider and we could see that the downgrade function was eventually returned
Service Fusion
A service breakdown occurs at the service provider. When an interface produces an exception, turn off the call to the interface, turn on the breaker, use the demotion function, and try the semi-open state again after a period of time. That is, try to put in some traffic. If normal, turn off the breaker to avoid unnecessary resource usage.
@HystrixCommand( // Downgrade function fallbackMethod = "selectByIdFallbackHandler", commandProperties = { // Whether service melting is enabled @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), // Request Threshold @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // time window @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // Error Ratio @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50") })
Indicates that when the number of requests is greater than 10 and the error ratio is more than 50%, the circuit breaker is turned on and half-open state is attempted after 10 seconds
Client's downgrade function is narrowing down the server
The downgrade function where the server broke down failed for me.
When a fuse occurs, the downgrade function is called directly
Use of Hystrix-dashboard
Apply Exposure Running Information
Hystrix-dashboard is the health dashboard of Hystrix-dashboard. To be monitored, we first need to introduce a monitoring information dependency
<!-- actuator Monitoring Information Improvement --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
Then add the information exposure configuration
For springboot above 2.x
management: endpoints: web: exposure: include: "*"
When the application starts, we need to see a line
2021-09-12 23:45:25.181 INFO 38634 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 17 endpoint(s) beneath base path '/actuator'
Indicate success
New Hystrix Dashboard Project
Add maven dependencies
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
Start the springboot application
@SpringBootApplication @EnableHystrixDashboard public class HystrixDashboard8400 { public static void main(String[] args){ SpringApplication.run(HystrixDashboard8400.class, args); } }
Visit HystrixDashboard
If you click in and keep loading, you need to access the interface that adds the @HystrixCommand annotation once to start displaying.
Fig. When too many failures occur, the breaker is turned on
When the breaker is turned on, the contents of the downgrade function are returned directly even if the interface parameters are correct
Okay, here you go, the components that follow, write when you're free, demo code github address begins