为什么用熔断器
假如服务A调用了服务B,服务B又调用了服务C,如果服务C发生异常或者其他原因导致服务C不可用,那么导致服务B,不可用,又导致服务A不可用。如果服务C是个很底层的服务,那么引起的其他不可用的服务可能就有很多,导致服务雪崩。而熔断器相当于一个服务的保护开关,如果某个服务不可用,那么这个开关打开,返回一个设置好的静态数据,或者空,或者另外一个被熔断器保护的服务。当发生错误的服务恢复后,开关就自动关闭,这样就不会导致大范围的服务不可用。
如何做
有两种方式
1. 使用Hystrix Clients
2. 使用Feign Hystrix Support
这里,我们先展示第一种方式的使用,第二种方式下一次在讨论。
如何做
一添加依赖
因为如果服务不可用,那么对不可用的服务的处理只能在调用端处理。所以,我们沿用之前的例子,在消费者工程中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
只需添加改依赖就可以了。
二 修改入口类
我们需要让工程开启熔断器的支持,在主类中添加注解@EnableCircuitBreaker
@Configuration
@ComponentScan(basePackages = "com.lzw.**")
@EnableAutoConfiguration
@EnableFeignClients(basePackages = "com.lzw.**")
@EnableCircuitBreaker
public class SpringCloudCustomerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudCustomerApplication.class, args);
}
}
三 为服务指定默认的失败方法
这个失败方式就是当调用的服务不可用时,就调用这个默认的方法返回。要注意的是,这个默认方法的参数必须和被注解的方法参数保持一致,否则会异常 @HystrixCommand 只能用在方法上。
@PostMapping("/study/")
@HystrixCommand(commandProperties = {
//可以这么设置
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000"),
},
//也可以这样设置
threadPoolProperties = {
/* @HystrixProperty(name = "coreSize", value = "30"),
@HystrixProperty(name = "maxQueueSize", value = "101"),
@HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"),*/
@HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "20"),
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000")
},fallbackMethod = "defaultStudy")
public String study(@RequestBody String name){
return study.study(name);
}
//如果参数与sdudy参数不一致,报错
public String defaultStudy1(){
return "study...";
}
public String defaultStudy(@RequestBody String name){
return "study...";
}
测试结果
启动注册中心,服务提供者,发送请求
把服务提供者关闭,再次请求