在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,为了解决这个问题,业界提出了断路器模型。如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystrix是5秒20次) 断路器将会被打开。我们通过前面的探讨已经知道 远程服务调用方式有两种,RestTemplate+Ribbon和Feign的调用方式,我们基于这两种方式来探讨断路器的实现。
在ribbon+RestTemplate使用断路器
在我们的工程中加入如下依赖:
org.springframework.cloud
spring-cloud-starter-hystrix
在程序启动类@EnableHystrix注解开启Hystri
SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class RibbionApplication {
public static void main(String[] args) {
SpringApplication.run(RibbionApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
在Service方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串
@Service
public class HiService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "hiError")
public String hiService(String name){
return restTemplate.getForObject("http://nacos-magic/sayHello/"+name,String.class);
}
public String hiError(String name){
return "hi"+name+" sorry! Error!";
}
}
当我们的远程服务不可用时,会直接调用 断路器方法返回,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。
Feign中使用断路器
Feign是自带断路器的,在D版本的Spring Cloud中,它没有默认打开。
需要在yml或者properties文件配置打开
feign:
hystrix:
enabled: true
只需要在FeignClient的接口的注解中加上fallback的指定类就行了:
@FeignClient(value = "nacos-magic",fallback = SayHelloServicehystrix.class)
public interface SayHelloService {
@RequestMapping(value="/sayHello/{name}",method = RequestMethod.GET)
String sayHi(@PathVariable("name") String name);
}
fallback 类需要实现对应的接口
@Component
public class SayHelloServicehystrix implements SayHelloService {
@Override
public String sayHi(String name) {
return "sorry "+name;
}
}
当我们的远程服务不可用时,会直接调用 fallback类实现的断路器方法返回,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。
参考链接:
Hystrix断路器