共计 1828 个字符,预计需要花费 5 分钟才能阅读完成。
简介
Hystrix 是 Netflix 开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。
断路器刨析
实时监测应用,如果发现在一定时间内失败次数 / 失败率达到一定阈值,就“跳闸”,断路器打开——此时,请求直接返回,而不去调用原本调用的逻辑。跳闸一段时间后(例如 15 秒),断路器会进入半开状态,这是一个瞬间态,此时允许一次请求调用该调的逻辑,如果成功,则断路器关闭,应用正常调用;如果调用依然不成功,断路器继续回到打开状态,过段时间再进入半开状态尝试——通过”跳闸“,应用可以保护自己,而且避免浪费资源;而通过半开的设计,可实现应用的“自我修复“。
解决方案
-
熔断模式
这种模式主要是参考电路熔断,如果一条线路电压过高,保险丝会熔断,防止火灾。放到我们的系统中,如果某个目标服务调用慢或者有大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。 -
隔离模式
这种模式就像对系统请求按类型划分成一个个小岛的一样,当某个小岛被火烧光了,不会影响到其他的小岛。例如可以对不同类型的请求使用线程池来资源隔离,每种类型的请求互不影响,如果一种类型的请求线程资源耗尽,则对后续的该类型请求直接返回,不再调用后续资源。这种模式使用场景非常多,例如将一个服务拆开,对于重要的服务使用单独服务器来部署,再或者公司最近推广的多中心。
-
限流模式
上述的熔断模式和隔离模式都属于出错后的容错处理机制,而限流模式则可以称为预防模式。限流模式主要是提前对各个类型的请求设置最高的 QPS 阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。这种模式不能解决服务依赖的问题,只能解决系统整体资源分配问题,因为没有被限流的请求依然有可能造成雪崩效应。
-
降级
降级与熔断紧密相关,熔断后业务如何表现,约定一个快速失败的 Fallback,即为服务降级
代码实现
- 加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 启动类加注解 @EnableCircuitBreaker
- 控制器加实现
测试
http://localhost:8010/movies/usersByFeign/1
{
"id": 1,
"username": "默认用户",
"name": "默认用户",
"age": 0,
"balance": 1
}
监控
持续不断地访问 http://localhost:8010/movies/users/1 多次(至少 20 次),再访问
http://localhost:8010/actuator/health,返现断路器已被开启。
{
"status": "UP",
"details": {
"diskSpace": {
"status": "UP",
"details": {
"total": 107374178304,
"free": 15773237248,
"threshold": 10485760
}
},
"db": {
"status": "UP",
"details": {
"database": "MySQL",
"hello": 1
}
},
"refreshScope": {"status": "UP"},
"discoveryComposite": {
"status": "UP",
"details": {
"discoveryClient": {
"status": "UP",
"details": {
"services": [
"shop-discovery-eureka-ha",
"shop-consumer-movie"
]
}
},
"eureka": {
"description": "Remote status from Eureka server",
"status": "UP",
"details": {
"applications": {
"SHOP-DISCOVERY-EUREKA-HA": 1,
"SHOP-CONSUMER-MOVIE": 1
}
}
}
}
},
"hystrix": {
"status": "CIRCUIT_OPEN",
"details": {
"openCircuitBreakers": ["MovieController::findByIdByFeign"]
}
}
}
}