其实吧,写Spring Cloud系列,我有时候觉得也挺难受的,因为Spring Cloud的微服务启动都需要一个一个来,并且在IDea中也需要占用比较大的内存,并且我本来可以一篇写完5大核心组件的,但是我却分了三篇,起初我交代过,这个系列,我将会慢慢来,因为我希望,将模块查分,这样我自己去理的时候也蛮清楚,别人看的时候,也轻松一点,所以我才一步一步完成微服务,这五大组件,其实都是可以聚合使用的,我只是为了把他单独划分出来讲解罢了。
并且,我写文章的时候,大多数理论先开始,然后再举例代码的,我希望通过此种方式,让我自己记忆深入一点,并且也让读者看到更加清楚,因为Spring Cloud对于微服务的理清楚,会比你学习的时候更加艰难,理清楚微服务之后再去学习,Spring Cloud会更加好一点。
好的,废话说多了,今天我们的主角是Hystrix,那么我们先了解什么是Hystrix。
Hystrix
介绍
Hystrix是Netflix开源的一款用于处理分布式系统中的延迟和容错问题的库。它提供了线程隔离、断路器、请求缓存、请求合并和服务降级等功能,以增加系统的弹性和可靠性。
Hystrix的底层实现机制主要包括以下几个关键组件:
- 线程隔离:Hystrix使用线程池隔离每个服务调用,使得服务调用之间互不影响,提高了系统的稳定性和可靠性。
- 断路器:Hystrix通过断路器机制来监控服务调用的状态,当服务调用失败率超过一定阈值时,断路器会打开,后续的请求将会被快速失败,避免对故障服务的连续调用。
- 请求缓存:Hystrix可以缓存请求的结果,当相同的请求再次发生时,可以直接返回缓存的结果,减少对后端服务的调用。
- 请求合并:Hystrix可以将多个相同类型的请求合并为一个批量请求,减少网络开销和提高性能。
- 服务降级:Hystrix可以定义服务调用失败时的降级逻辑,返回一个备选的结果或执行备选的逻辑,保证系统的可用性。
Hystrix可以解决分布式系统中的故障和延迟问题,提供了以下几个主要的功能和优势:
- 防止级联故障:通过断路器机制,Hystrix可以防止故障的服务调用对整个系统的影响,避免级联故障的发生。
- 快速失败和快速恢复:Hystrix能够快速失败并快速恢复,当服务调用失败时,可以快速返回失败结果或备选结果,提高系统的响应速度。
- 提供容错能力:Hystrix通过服务降级和备选逻辑,可以在服务不可用或出现故障时提供备选的处理方式,保证系统的可用性。
- 监控和度量:Hystrix提供了丰富的监控和度量功能,可以实时监控服务调用的状态和性能指标,帮助开发者了解系统的运行情况。
在Spring Cloud中,Hystrix被广泛应用于微服务架构中的服务调用和容错处理。通过与Ribbon和Feign等组件的集成,Spring Cloud可以自动为服务调用添加Hystrix的功能,提供了更强大的容错能力和弹性。同时,Spring Cloud还提供了Hystrix Dashboard和Turbine等工具,用于监控和可视化Hystrix的运行状态和指标。
注意,实际上Spring Cloud的组件是可以集成使用的,我将至分开是更好的了解这五大组件的功能,以及更好的了解Spring Cloud的微服务的搭建。
老样子,搭建服务目录如下:
pom.xml
<?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>springCloud</artifactId>
<groupId>com.miaow</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<description>Hystrix熔断降级</description>
<artifactId>hystrix</artifactId>
<name>hystrix</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 2383
spring:
application:
name: hystrix-demo
#路由前缀
zuul:
prefix: /api
# eureka客户端注册到Eureka注册中心,切记需要启动eureka服务
eureka:
client:
service-url:
defaultZone: http://localhost:1000/eureka
启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableHystrix
@EnableEurekaClient
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class);
}
}
以下介绍这五个注解
@SpringBootApplication
@SpringBootApplication是一个组合注解,包含了@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三个注解。它的作用是标识一个Spring Boot应用程序的主类,用于启动Spring Boot应用程序。
@EnableDiscoveryClient
@EnableDiscoveryClient注解用于启用服务注册与发现功能,它可以让应用程序作为一个Eureka客户端来注册到Eureka Server,并从Eureka Server中获取其他服务的信息。
@EnableCircuitBreaker
@EnableCircuitBreaker注解用于启用断路器功能,它可以让应用程序使用Hystrix来实现断路器模式,当服务调用失败时,自动熔断服务,避免服务雪崩。
@EnableHystrix
@EnableHystrix注解是@EnableCircuitBreaker的一个别名,用于启用Hystrix断路器功能。
@EnableEurekaClient
@EnableEurekaClient注解用于启用Eureka客户端功能,它可以让应用程序作为一个Eureka客户端来注册到Eureka Server,并从Eureka Server中获取其他服务的信息。
至此,我们以及启动了6个微服务了:
熔断降级案例
好的,既然我们将Spring Cloud的五大核心组件已经介绍完毕了,那么我们就用熔断降级来完成一个案例吧,注意这是一个案例:
这是我的目录结构:
我们创建一个电影推荐服务MovieRecommendationService,该服务提供一个方法getRecommendedMovies()来获取推荐的电影列表。在这个例子中,我们假设该服务可能会出现故障或延迟。
import org.springframework.stereotype.Service;
@Service
public class MovieRecommendationService {
public List<String> getRecommendedMovies() {
// 模拟电影推荐服务的调用
// 这里可以是一个远程服务调用或者其他耗时操作
// 假设这里可能会出现故障或延迟
// 返回一个默认的电影列表
return Arrays.asList("Movie 1", "Movie 2", "Movie 3");
}
}
然后,我们使用Hystrix来包装MovieRecommendationService,实现服务降级和断路器的功能。
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class HystrixMovieRecommendationService {
private final MovieRecommendationService movieRecommendationService;
@Autowired
public HystrixMovieRecommendationService(MovieRecommendationService movieRecommendationService) {
this.movieRecommendationService = movieRecommendationService;
}
@HystrixCommand(fallbackMethod = "getDefaultMovies")
public List<String> getRecommendedMovies() {
return movieRecommendationService.getRecommendedMovies();
}
public List<String> getDefaultMovies() {
// 定义一个备选的电影列表
return Arrays.asList("Default Movie 1", "Default Movie 2", "Default Movie 3");
}
}
在上面的代码中,我们使用@HystrixCommand
注解来标记getRecommendedMovies()
方法,当调用该方法时,Hystrix会自动包装该方法,并在电影推荐服务调用失败时,调用fallbackMethod
指定的方法getDefaultMovies()
来返回备选的电影列表。
最后,我们可以在Spring Boot应用程序中使用HystrixMovieRecommendationService
来获取推荐的电影列表。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MovieController {
private final HystrixMovieRecommendationService movieRecommendationService;
@Autowired
public MovieController(HystrixMovieRecommendationService movieRecommendationService) {
this.movieRecommendationService = movieRecommendationService;
}
@GetMapping("/movies")
public List<String> getRecommendedMovies() {
return movieRecommendationService.getRecommendedMovies();
}
}
在上面的代码中,我们创建了一个MovieController
,其中注入了HystrixMovieRecommendationService
,并提供了一个GET请求的接口/movies
来获取推荐的电影列表。
这样,当调用/movies接口时,Hystrix
会自动对getRecommendedMovies()
方法进行包装,当电影推荐服务调用失败时,会返回getDefaultMovies()
方法定义的备选电影列表。
然后我们重新启动服务,访问:
http://localhost:2383/movies