1. 背景
Hystrix 是一个容错框架,当多个服务可能导致滚雪球效应时,通过熔断回路来尽可能的保护一些服务。
2.知识
由于每个无法单元都在不同的进程中运行,通过远程调用的方式互相调用, 就有可能因为网络原因或是服务不健康而出现故障或延迟。进而也导致调用方也出现延迟, 若调用方的请求不断累加, 最后就会形成任务积压导致自身服务也瘫痪。
若一个服务出现故障,而引发故障的蔓延,最终导致整个系统的瘫痪,为了解决这样的问题, 产生了断路器等一系列的服务保护机制。
Spring Cloud Circuit breaker提供了可以支持不同“断路器实现的抽象”。它提供了在应用程序中使用的一致的API,允许开发人员选择最适合应用程序需求的断路器实现。
它支持下面几种:
- Netfix Hystrix
- Resilience4J
- Sentinel
- Spring Retry
创建断路器 创建断路器,可以使用CircuitBreakerFactory API。当您在类路径中包含Spring Cloud Circuit Breaker “启动器”时,将自动为您创建实现此API的bean。
3. 示例
添加依赖
代码语言:javascript复制dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-hystrix', version: '2.2.8.RELEASE'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
创建断路器,步骤:
- 1、装载一个 CircuitBreakerFactory
- 2、通过 cbFactory.create().run()方法执行你的任务。
格式示例:
代码语言:javascript复制return cbFactory.create("slow").run(() -> rest.getForObject("/slow", String.class), throwable -> "fallback");
完整示例:
代码语言:javascript复制package ribbonconsumer.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.time.Duration;
/**
* @description:
* @author: zhangyunfei
* @date: 2021/5/11 16:35
*/
@RestController
public class ReadController {
@Autowired
private CircuitBreakerFactory cbFactory;
@Autowired
private RestTemplate restTemplate;
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@RequestMapping(value = "/read", method = RequestMethod.GET)
public String index() {
return cbFactory.create("slow").run(() -> {
long start = System.currentTimeMillis();
String str = restTemplate.getForObject("http://HELLO-SERVICE-1/hello", String.class);
long end = System.currentTimeMillis();
log("Spend time : " (end - start));
return str;
},
throwable -> "on error");
}
private static void log(String str) {
System.out.println(str);
}
}
4. 扩展
配置超时时间
代码语言:javascript复制hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
我的demo地址:https://github.com/vir56k/demo/tree/master/springboot/hystrix_demo
注意:在服务降级逻辑中, 我们需要实现一个通用的响应结果, 并且该结果的处理逻辑应当是从 缓存或是根据一些静态逻辑来获取。
5.参考:
《Spring Cloud微服务实战》 https://spring.io/projects/spring-cloud-circuitbreaker https://juejin.cn/post/6844903855545663502