在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,为了解决这个问题,业界提出了断路器模型。如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是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断路器