设为首页 加入收藏

TOP

Spring Cloud(四):服务容错保护 Hystrix【Finchley 版】(二)
2019-09-17 18:30:37 】 浏览:49
Tags:Spring Cloud 服务 容错 保护 Hystrix Finchley
s
8ms 3ms
99 百分位 28ms 37ms 9ms

在 99% 的情况下,使用线程池隔离的延迟有 9ms,对于大多数需求来说这样的消耗是微乎其微的,更何况为系统在稳定性和灵活性上所带来的巨大提升。虽然对于大部分的请求我们可以忽略线程池的额外开销,而对于小部分延迟本身就非常小的请求(可能只需要 1ms),那么 9ms 的延迟开销还是非常昂贵的。实际上 Hystrix 也为此设计了另外的一个解决方案:信号量(Semaphores)。

Hystrix 中除了使用线程池之外,还可以使用信号量来控制单个依赖服务的并发度,信号量的开销要远比线程池的开销小得多,但是它不能设置超时和实现异步访问。所以,只有在依赖服务是足够可靠的情况下才使用信号量。在 HystrixCommand 和 HystrixObservableCommand 中 2 处支持信号量的使用:

  • 命令执行:如果隔离策略参数 execution.isolation.strategy 设置为 SEMAPHORE,Hystrix 会使用信号量替代线程池来控制依赖服务的并发控制。
  • 降级逻辑:当 Hystrix 尝试降级逻辑时候,它会在调用线程中使用信号量。

信号量的默认值为 10,我们也可以通过动态刷新配置的方式来控制并发线程的数量。对于信号量大小的估算方法与线程池并发度的估算类似。仅访问内存数据的请求一般耗时在 1ms 以内,性能可以达到 5000rps,这样级别的请求我们可以将信号量设置为 1 或者 2,我们可以按此标准并根据实际请求耗时来设置信号量。

断路器模式

断路器模式源于 Martin Fowler 的 Circuit Breaker 一文。“断路器” 本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,“断路器” 能够及时的切断故障电路,防止发生过载、发热、甚至起火等严重后果。

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),直接切断原来的主逻辑调用。但是,在 Hystrix 中的断路器除了切断主逻辑的功能之外,还有更复杂的逻辑,下面我们来看看它更为深层次的处理逻辑。

断路器开关相互转换的逻辑如下图:

当 Hystrix Command 请求后端服务失败数量超过一定阈值,断路器会切换到开路状态 (Open)。这时所有请求会直接失败而不会发送到后端服务。

这个阈值涉及到三个重要参数:快照时间窗、请求总数下限、错误百分比下限。这个参数的作用分别是:
快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的 10 秒。
请求总数下限:在快照时间窗内,必须满足请求总数下限才有资格进行熔断。默认为 20,意味着在 10 秒内,如果该 Hystrix Command 的调用此时不足 20 次,即时所有的请求都超时或其他原因失败,断路器都不会打开。
错误百分比下限:当请求总数在快照时间窗内超过了下限,比如发生了 30 次调用,如果在这 30 次调用中,有 16 次发生了超时异常,也就是超过 50% 的错误百分比,在默认设定 50% 下限情况下,这时候就会将断路器打开。

断路器保持在开路状态一段时间后 (默认 5 秒),自动切换到半开路状态 (HALF-OPEN)。这时会判断下一次请求的返回情况,如果请求成功,断路器切回闭路状态 (CLOSED),否则重新切换到开路状态 (OPEN)。

使用 Feign Hystrix

因为熔断只是作用在服务调用这一端,因此我们根据上一篇的示例代码只需要改动 eureka-consumer-feign 项目相关代码就可以。

POM 配置

因为 Feign 中已经依赖了 Hystrix 所以在 maven 配置上不用做任何改动。

配置文件

在原来的 application.yml 配置的基础上修改

1
2
3
4
5
6
7
8
9
10
11
12
spring:
application:
name: eureka-consumer-feign-hystrix
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka/
server:
port: 9003
feign:
hystrix:
enabled: true

 

创建回调类

创建 HelloRemoteHystrix 类实现 HelloRemote 中实现回调的方法

1
2
3
4
5
6
7
8
9
@Component
public class HelloRemoteHystrix implements HelloRemote {

@Override
public String hello(@RequestParam(value = "name") String name) {
return "Hello World!";
}

}

 

添加 fallback 属性

HelloRemote类添加指定 fallback 类,在服务熔断的时候返回 fallback 类中的内容。

1
2
3
4
5
6
7
@FeignClient(name = "eureka-producer", fallback = HelloRemoteHystrix.class)
public interface HelloRemote {

@GetMapping("/hello/")
String hello(@RequestParam(value = "name") String name);

}

 

别的就不用动了,很简单吧!

测试

依次启动 eureka-server、eureka-producer 和刚刚的 eureka-consumer-hystrix 这三个项目。

访问:http://localhost:9003/hello/windmt
返回:[0]Hello, windmt! Sun Apr 15 23:14:25 CST 2018

说明加入 Hystrix 后,不影响正常的访问。接下来我们手动停止 eureka-producer 项目再次测试:

访问:http://localhost:9003/hello/windmt
返回:Hello World!

这时候我们再次启动 eureka-producer 项目进行测试:

访问:http://localhost:9003/hello/windmt
返回:[0]Hello, windmt! Sun Apr 15 23:14:52 CST 2018

根据返回结果说明熔断成功。

总结

通过使用 Hystrix,我们能方便的防止雪崩效应,同时使系统具有自动降级和自动恢复服务的效果。

相关阅读

Spring Cloud(一):服务治理技术概览
Spring Cloud(二):服务注册与发现 Eureka
Spring Cloud(三):服务提供与调用 Eureka
Spring Cloud(四):服务容错保护 Hystrix
Spring Cloud(五):Hystrix 监控面板
Spring Cloud(六):Hystrix 监控数据聚合 Turbine
Spring Cloud(七):配置中心(Git 版与动态刷新)
Spring Cloud(八):配置中心(服务化与高可用)
Spr

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇测试驱动开发 TDD 下一篇angular 表单验证

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目