在分布式环境中,服务之间的依赖调用正常情况下如下图:
但是,分布式环境中服务的宕机,超时是经常发生的,为了不导致分布式服务的雪崩效应,Hystrix在对服务的调用增加的延迟和容错逻辑。
熔断触发降级
- 熔断的目的是为了起到保护服务的作用
- 降级
- 主动降级,大促的时候关闭非核心服务.
- 被动降级, 熔断降级、限流降级
要使用Hystrix在pom文件中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
Api方式使用Hystrix
// 自定义一个HystrixCommand实现
public class HystrixService extends HystrixCommand<String> {
// 要执行的任务
private Supplier<String> supplier;
//
public HystrixService(HystrixCommandGroupKey group, Supplier<String> supplier) {
this(group, 3000);
this.supplier = supplier;
}
private HystrixService(HystrixCommandGroupKey group, int executionIsolationThreadTimeoutInMilliseconds) {
super(group, executionIsolationThreadTimeoutInMilliseconds);
}
// 执行封装的业务
@Override
protected String run() throws Exception {
return supplier.get();
}
// 降级调用的方法
@Override
protected String getFallback() {
return "fallback";
}
}
使用
@RestController
@RequestMapping("/api/v0")
public class HystrixController {
@Autowired
private RestTemplate restTemplate;
// 普通请求
@GetMapping("/baidu/1")
public Object helloBaidu1() {
String forObject = restTemplate.getForObject("https://www.baidu.com", String.class);
return forObject;
}
// 带熔断的请求
@GetMapping("/baidu/2")
public Object helloBaidu2() {
// 静态代理
HystrixService hystrixService = new HystrixService(
HystrixCommandGroupKey.Factory.asKey("outerServer"),// 资源分组隔离
() -> restTemplate.getForObject("https://www.baidu.com", String.class)
);
// 执行模板方法
return hystrixService.execute();
}
}
HystrixCommand#execute()
public R execute() {
try {
return queue().get();
} catch (Exception e) {
throw Exceptions.sneakyThrow(decomposeException(e));
}
}
注解方式
//注解方式
@HystrixCommand(commandProperties =
{
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),// 开启熔断
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"),// 10秒内最小请求量
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),//熔断时间窗口
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),// 错误百分比
@HystrixProperty(name = "execution.timeout.enabled", value = "true"),// 调用超时开启
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),// 调用超时
},
fallbackMethod = "fallbackBaidu"// 降级调用方法
)
@GetMapping("baidu3")
public Object helloBaidu3() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
String forObject = restTemplate.getForObject("https://www.baidu.com", String.class);
return forObject;
}
// 降级方法,同一个类中
public Object fallbackBaidu() {
return "fallbackBaidu";
}
同时需要在启动类上加上@EnableHystrix
或则@@EnableCircuitBreaker
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Import(EnableCircuitBreakerImportSelector.class)
public @interface EnableCircuitBreaker {
}
@Order(Ordered.LOWEST_PRECEDENCE - 100)
public class EnableCircuitBreakerImportSelector extends
SpringFactoryImportSelector<EnableCircuitBreaker> {
@Override
protected boolean isEnabled() {
return getEnvironment().getProperty("spring.cloud.circuit.breaker.enabled", Boolean.class, Boolean.TRUE);
}
}