SpringCould Hystrx熔断器使用
为什么要用
- tomcat中线程出错不会立即释放,会驻留
- 微服务中,一个请求可能需要多个微服务接口才能实现,会形成复杂的调用链路。
- 如果某服务出现异常,请求阻塞,用户得不到响应,容器中线程不会释放,于是越来越多用户请求堆积,越来越多线程阻塞。
- 单服务器支持线程和并发数有限,请求如果一直阻塞,会导致服务器资源耗尽,从而导致所有其他服务都不可用,从而形成雪崩效应;
- Hystrix解决雪崩问题的手段,主要是服务降级(兜底),线程隔离;
引入熔断的依赖坐标:
在服务提供者模块进行配置
- consumer_service中加入依赖
<!--熔断Hystrix starter-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
开启熔断的注解
//注解简化写法:微服务中,注解往往引入多个,简化注解可以使用组合注解。@SpringCloudApplication =等同于@SpringBootApplication+@EnableDiscoveryClient+@EnableCircuitBreaker
@SpringBootApplication
@EnableDiscoveryClient//开启服务发现
@EnableCircuitBreaker//开启熔断
public class ConsumerApplication {
@Bean
@LoadBalanced//开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args);
}
}
编写服务降级处理方法
使用@HystrixCommand定义fallback方法。
@RequestMapping("/ribbonconsumer/{id}")
@HystrixCommand(fallbackMethod ="queryByIdFallback")
public String queryById(@PathVariable Long id){
String url = String.format("http://user-service/user/%d", id);
return restTemplate.getForObject(url,String.class);
}
public String queryByIdFallback(Long id){
return "对不起,网络太拥挤了!";
}
模拟服务故障的情况
停掉所有的服务,然后进行访问
配置熔断策略
- 常见熔断策略配置
- 熔断后休眠时间:sleepWindowInMilliseconds
- 熔断触发最小请求次数:requestVolumeThreshold
- 熔断触发错误比例阈值:errorThresholdPercentage
- 熔断超时时间:timeoutInMilliseconds
# 配置熔断策略:
# 强制打开熔断器 默认false关闭的。测试配置是否生效
hystrix.command.default.circuitBreaker.forceOpen: false
# 触发熔断错误比例阈值,默认值50%
hystrix.command.default.circuitBreaker.errorThresholdPercentage: 20
# 熔断后休眠时长,默认值5秒
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds: 60000
# 熔断触发最小请求次数,默认值是20
hystrix.command.default.circuitBreaker.requestVolumeThreshold: 5
# 熔断超时设置,默认为1秒
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 2000
测试熔断策略
在服务中加入延迟3秒,这已经超出了熔断策略的超时配置
测试出错的情况
访问id为1出错
访问id为2不出错
多次访问id为1后就熔断了
等待60秒之后会尝试进行测试