概述

本系列源码地址:https://github.com/lhmyy521125/toher-springcloud-sample

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过 RPC 相互调用,在 Spring Cloud 中可以用 RestTemplate + Ribbon 和 Feign 来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证 100% 可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet 容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩” 效应

为了解决这个问题,业界提出了断路器模型

Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:

springclouid 的idea 客户端_断路器


较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开

springclouid 的idea 客户端_SpringCloud 熔断机制_02


断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值

准备工作

本章因为需要介绍Ribbon 和feign 熔断器使用,我们分别需要将 toher-springcloud-sample2-ribbon 以及 toher-springcloud-sample3-feign 工程都分别复制一份,分别命名toher-springcloud-sample4-ribbon-hystrix 、toher-springcloud-sample5-feign-hystrix

在ribbon使用断路器

IDEA打开toher-springcloud-sample4-ribbon-hystrix,启动eureka-service工程 , 启动service-hello工程, 我们接下来改造service-ribbon工程,
首先在pox.xml文件中加入spring-cloud-starter-netflix-hystrix的起步依赖:

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

修改工程的启动类 加入@EnableHystrix 开启熔断器

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class ServiceRibbonApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceRibbonApplication.class, args);
    }

    //通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

改造HelloRibbonService 在 Service 中增加 @HystrixCommand 注解

@Service
public class HelloRibbonService {

    @Autowired
    private RestTemplate restTemplate;

    //@HystrixCommand 指明该方法开启熔断,并指定了fallbackMethod熔断方法 helloError
    @HystrixCommand(fallbackMethod = "helloError" )
    public String helloRibbon(String name) {
        return restTemplate.getForObject("http://SERVICE-HELLO/hello?name=" + name, String.class);
    }

    public String helloError(String name) {
        return "hi,"+name+",sorry, this is ribbon error!";
    }

}

接下来及逆行测试,现在启动service-ribbon工程 ,访问http://localhost:9003/helloRibbon?name=Ribbon 可以看到

hi Ribbon ,this is Ribbon Project , i am from port:9001

我们断开服务提供者 service-hello ,再看输出结果:说明熔断成功,因为它会执行快速失败,直接返回相关信息,而不是等待响应超时,这很好的控制了容器的线程阻塞

hi,Ribbon,sorry, this is ribbon error!!

在feign使用断路器

Feign 是自带熔断器的,但默认是关闭的。需要在配置文件中配置打开它,IDEA打开toher-springcloud-sample5-feign-hystrix在配置文件增加以下代码:

feign:
  hystrix:
    enabled: true

改造service-feign工程,还记得我们之前创建的 HelloFeignService 细心的小伙伴会发现是一个接口(interface) ,嗯,,没错就是给我们去实现的, 创建一个实现类

@Component
public class HelloFeignServiceHystric implements HelloFeignService {

    @Override
    public String helloFeign(String name) {
        return "hi, "+name+" sorry,this is feign hystrix  error";
    }
}

接下来只需要在FeignClient的HelloFeignService接口的注解中加上fallback的指定类

@FeignClient(value = "SERVICE-HELLO" ,fallback = HelloFeignServiceHystric.class)
public interface HelloFeignService {
    @RequestMapping(value = "/hello")
    String helloFeign(@RequestParam(value = "name") String name);
}

分别启动 eureka-server 、service-hello 、 service-feign,访问 http://localhost:9004/helloFeign?name=Feign

hi Feign ,this is Feign Project , i am from port:9002

关闭服务提供者 service-hello

hi, Feign sorry,this is feign hystrix error

结语

本章节主要介绍了熔断器Hystrix的使用,并分为Ribbon 和 Feign 两种形式的实现;

下一篇:熔断器的监控