Hystrix(续二)
服务熔断
添加 Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @GetMapping("/payment/circuit/{id}") @HystrixCommand(fallbackMethod = "paymentCircuitBreakerHandler", commandProperties = { @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), }) public String paymentCircuitBreaker(@PathVariable("id") Integer id) { if (id < 0) { throw new RuntimeException("id 不能为负数"); } String serialNumber = IdUtil.simpleUUID(); return Thread.currentThread().getName() + "\t" + "调用成功,流水号:" + serialNumber; }
public String paymentCircuitBreakerHandler(Integer id) { return "id 不能为负数,请重试。当前 id:" + id; }
|
测试
分别启动 Eureka-Server 和 Payment5 模块后,浏览器访问:127.0.0.1:8005/payment/circuit/997,能够正常调用。然后连续快速地多次访问:127.0.0.1:8005/payment/circuit/-997,调用的都是 fallback 方法,最后再多次访问:127.0.0.1:8005/payment/circuit/997,会发现一开始还是调用的 fallback 方法,但是多试几次之后就又恢复正常了。
断路器开启和关闭的条件:
- 到达以下阀值,断路器将会开启:
- 当满足一定的阀值的时候(默认10秒内超过20个请求次数)
- 当失败率达到一定的时候(默认10秒内超过50%的请求失败)
- 当开启的时候,所有请求都不会进行转发。
- 一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。
备注:
上面的注解参数,不懂的可以点击下面的链接进行查看。
https://segmentfault.com/a/1190000016024957
工作流程
![]()
- 创建 HystrixCommand (用在依赖的服务返回单个操作结果的时候)或 HystrixObserableCommand(用在依赖的服务返回多个操作结果的时候)对象。
- 执行命令。
- 响应是否已缓存?如果为此命令启用了请求缓存,并且请求的响应在缓存中可用,则此缓存的响应将立即返回。
- 检查断路器是否为打开状态?如果断路器是打开的,那么 Hystrix 不会执行命令,而是转接到 fallback 处理逻辑;如果断路器是关闭的,检查是否有可用资源来执行命令。
- 线程池/队列/信号量是否占满?如果已经被占满,那么 Hystrix 也不会执行命令,而是转接到 fallback 处理理辑。
- Hystrix 根据我们使用的对象来决定采取什么样的方式去请求依赖服务。
- Hystix 将处理后的信息报告给断路器,而断路器会维护一组计数器来统计这些数据。断路器会使用这些统计数据来决定是否要将断路器打开,来对某个依赖服务的请求进行熔断。
- 当命令执行失败的时候,Hystix 会进入 fallback 尝试回退处理,通常也称此操作为“服务降级”。
- 当 Hystrix 命令执行成功之后,它会将处理结果直接返回或是以 Observable 的形式返回。
图形化仪表盘
准备工作
创建一个 Module,一个空的 Maven 项目。并导入下面的依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> <version>2.2.10.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
|
编写配置文件
1 2 3 4 5 6 7
| server: port: 9001
hystrix: dashboard: proxy-stream-allow-list: "localhost"
|
主启动类
1 2 3 4 5 6 7 8 9 10 11 12 13
| package ml.guest997;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication @EnableHystrixDashboard public class Dashboard { public static void main(String[] args) { SpringApplication.run(Dashboard.class, args); } }
|
添加配置(Payment5 模块)
1 2 3 4 5 6
| #配置服务监控路径 management: endpoints: web: exposure: include: "hystrix.stream"
|
测试
分别启动 Eureka-Server、Payment5 和 Dashboard 模块后,浏览器访问:127.0.0.1/hystrix,输入监控路径:http://localhost:8005/actuator/hystrix.stream,如下图。
![]()
浏览器开一个新窗口访问:127.0.0.1:8005/payment/circuit/997,会出现如下图的画面。
![]()