雪崩效应

在微服务中,每个微服务都是通过RPC进行交互的,根据前两章中我们可以通过Ribbon,RestTemplate和Feign进行调用。

网络充满了许多不确定的因素,例如网络原因导致了某个微服务不可用,大量的请求涌入(或是别的微服务调用),会迅速消耗完Servlet容器的线程资源。造成服务器宕机。

微服务之间的相互调用会传递雪崩效应。

断路器

当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。 断路器模式

我们通过netflix的hystrix实现断路器。我们要通过集成Ribbon和hystrix或Feign和hystrix实现对无法回应的请求的阻塞。

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

Ribbon中使用断路器

  1. 使用@EnableHystrix开启Hystrix断路器
    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient
    @EnableHystrix	//开启Hystrix断路器
    public class SpringCloudClientRibbonApplication {
     public static void main(String[] args) {
         SpringApplication.run(SpringCloudClientRibbonApplication.class, args);
     }
     @Bean
     @LoadBalanced
     RestTemplate restTemplate(){
         return new RestTemplate();
     }
    }
    
  2. 断路器适用于Service层,当Ribbon通过RestTemplate进行负载均衡时,如果Ribbon无法进行转发时,就会返回调用Fallback方法。
    @Service
    public class HelloService {
     @Autowired
     private RestTemplate restTemplate;
     @HystrixCommand(fallbackMethod="hiError")	//如果调用服务,就会调用hiError方法。并且会将形参进行传递。
     public String hiService(String name){
         return restTemplate.getForObject("http://SERVICE-HI/hi?name=" + name, String.class);
     }
     public String hiError(String name){
         return "Sorry " + name + ", Error happened!";
     }
    }
    

Feign中使用Hystrix

Finchley版本的Spring Cloud中Hystrix没有打开,需要在配置文件中打开Hystrix

feign.hystrix.enabled=true
  1. 在负载均衡的注解(@FeignClient)中加入FallBack所实行的类。
    //定义一个feign接口,通过@ FeignClient(“服务名”),来指定调用哪个服务。
    //fallback定义了断路器的默认方法。
    @FeignClient(value="SERVICE-HI", fallback=HelloServiceHystrix.class)
    public interface HelloService {
     @RequestMapping(value="/hi")
     public String sayHello(@RequestParam("name") String name);
    }
    //实现一个类继承HelloService,HelloService是默认的负载均衡的方法。
    //必须将该类注册到Spring容器中,这样就能通过反射调用到默认的断路方法。
    @Component
    public class HelloServiceHystrix implements HelloService {
     @Override
     public String sayHello(String name) {
         return "Hello" + name + ", Error happend!";
     }
    }
    

Result

  1. 当SERVICE-HI是UP时:
    • Hello sean, return from port: 8766
  2. 当SERVICE-HI无法调用时:
    • Sorry sean, Error happened!

Reference

  1. SpringCloud教程第4篇:Hystrix(F版本)