SpringCloud极简入门(七)熔断器Hystrix
作者:陈刚,叩丁狼高级讲师。原创文章,转载请注明出处。
一.为什么需要熔断器
我们知道我们的项目会被分成很多的服务,而每个服务是独立运行的,服务和服务之间通过REST API 实现远程相互调用,既然是远程调用就有可能会因为网络故障,或被调用的服务本身出现问题而造成服务调用延迟,调用失败等问题,而这些问题可能造成调用方对外部服务也调用失败,从而造成一些列连锁反应,甚至造成整个应用瘫痪。
例如:服务A调用服务B,而服务B调用服务C,如果服务B调用服务C出现故障,那么服务A调用服务B可能也会出现连锁反应,那么整个应用可能都会出现问题。而这种效果也被叫做雪崩效应。
二.什么是熔断器Hystrix
熔断器就好比家里电路装置的“保险”,当电路断路,那么“保险”装置的“保险丝”就会被熔断,从而达到断开电路的效果,以防止不良后果。而Spring Cloud Hystrix 实现了熔断器,线程隔离等一些列的服务保护功能,当Hystrix判定请求出现故障,会立马对请求做出响应动作,不会继续执行正常请求逻辑,请求线程也不会处于阻塞状态,从而有效防止雪崩效应。
三.实现基于Ribbon使用熔断器
1.改造项目Consumer,引入 hystrix 的依赖包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.主程序打上@EnableHystrix标签,开启熔断器功能
/**
* @EnableHystrix: 开启 hystrix ,开启熔断器功能
*/
@EnableHystrix
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
//通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。
//RestTemplate是spring内置的http请求封装
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
3.在ConsumerController中的方法上打上注解 @HystrixCommand注解,开启熔断器功能
//HystrixCommand:给方法启用熔断器功能,当出现访问故障,自动调用 fallbackMethod 指向的方法
@RequestMapping("/consumer")
@HystrixCommand(fallbackMethod = "errorMethod")
public String consumer(@RequestParam("name") String name){
String result = restTemplate.getForObject("http://PRODUCER/provide?name="+name,String.class);
return result;
}
public String errorMethod(String name){
return "你好,"+name+",访问错误";
}
4.测试:一次启动 EurekaServer,Producer,Consumer服务,访问地址http://localhost:3333/consumer?name=zs ,你将会看到“zs:你好呀这里是Producer服务”,
当关掉 Producer服务,再访问会出现: "你好,zs,访问错误";
当Producer服务关掉,那么Consumer服务不能调用Producer服务的接口,那么马上回执行errorMethod方法进行故障处理。
四.实现基于feign的熔断器
feign默认实现了熔断器功能,不需要引入额外的包
1.基于Consumer项目,配置文件开启熔断器功能
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/ #服务地址
server:
port: 3333
spring:
application:
name: consumer1
#开启熔断器
feign:
hystrix:
enabled: true
2.MyFeignClient接口开启熔断器功能,给@FeignClient标签添加fallback属性指定熔断器逻辑处理类
//PRODUCER:指向要访问的服务
//configuration = FooConfiguration.class Feign Client配置类,指定负载均衡策略
//fallback = MyFeignClientImpl.class: MyFeignClient接口的实现类,需要复写 provide方法,并实现错误处理逻辑
//当访问出现故障,程序会自动调用实现类的 provide方法的错误处理逻辑。
@FeignClient(value = "PRODUCER",configuration = FooConfiguration.class,fallback = MyFeignClientImpl.class)
public interface MyFeignClient {
//当此方法别调用会自动请求到 PRODUCER服务的 /provide 资源
@RequestMapping(value = "/provide")
public String provide(@RequestParam("name") String name);
}
3.定义类 MyFeignClientImpl
@Component
public class MyFeignClientImpl implements MyFeignClient {
@Override
public String provide(String name) {
return "你好,"+name+",访问出现错误";
}
}
WechatIMG9.jpeg4.测试:一次启动EurekaServer,Producer,Consumer,访问地址:http://localhost:3333/feign?name=zs ,你将会看到 “zs:你好呀这里是Producer服务”,
然后关闭Producer服务,再访问将会看到 “你好,zs,访问出现错误”,当Consomer服务找不到Producer服务接口时就自动调用了MyFeignClientImpl实现类的熔断器逻辑处理方法。