在微服务架构当中,根据业务来拆分成一个一个的微服务,服务和服务之间可以相互调用(RPC),Spring Cloud可以用RestTemplate+Ribbon和Feign来实现,为了保证高可用,单个服务会集群部署,由于网络或者自身原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现阻塞,此时如果有大量的请求涌入,Servlet容器就会被消耗完毕,由于服务和服务之间有依赖姓,因此故障会进行传播,从而对整个系统造成灾难性的后果。
为了解决整个问题,就需要断路器。
1 断路器简介
Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:
较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。
下面我们通过实例看看如何使用Ribbon来调用服务,并实现客户端的均衡负载。
2 准备工作
篇文章是基于 Spring Cloud 服务消费者(Feign) 来实现的。
3 在Ribbon当中使用断路器
第一步:添加依赖
在spring-cloud-consumer-ribbon项目当中添加依赖,代码如下:
org.springframework.cloudspring-cloud-starter-netflix-hystrix
第二步:在入口类Application当中添加注解
在入口类Application添加注解@EnableHystrix
第三步:改造HelloService
改造HelloService类,在sayHelloFromProvider方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串,字符串为"hi,"+name+",sorry,error!",代码如下:
packagecom.brimen.springcloudconsumerribbon.service;importcom.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.web.client.RestTemplate;@ServicepublicclassHelloService{@Autowired RestTemplate restTemplate;@HystrixCommand(fallbackMethod ="helloError")publicString sayHelloFromProvider(String name) {returnrestTemplate.getForObject("http://spring-cloud-provide/hello/gethello?name="+ name, String.class); }publicString helloError(String name){return"hi,"+name+",sorry,error!"; }}
第四步:启动工程
依次启动spring-cloud-eureka、spring-cloud-provide和spring-cloud-consumer-ribbon工程
第五步:访问spring-cloud-consumer-ribbo的接口
打开浏览器,访问:http://localhost:8082/hello/gethello
第六步:关闭spring-cloud-provide工程
关闭spring-cloud-provide工程,再次进行访问:http://localhost:8082/hello/gethello
这说明spring-cloud-provide工程不可用,当spring-cloud-consumer-ribbo调用spring-cloud-provide的接口时,执行失败,因此调用了断路器的方法
4 在Feign当中使用断路器
第一步:在配置文件当中进行配置
Feign当中是自带断路器的,在D版本之后之后,它没有默认打开,需要在配置文件当中进行配置,配置如下:
eureka:client:serviceUrl:defaultZone:http://localhost:8080/eureka/ #1server:port:8084spring:application:name:spring-cloud-consumer-feign #2feign:hystrix:enabled:true #3#1、服务注册中心的地址#2、服务的名称,作为其它服务调用的服务名#3、开启断路器
第二步:改造Service接口
packagecom.brimen.springcloudconsumerfeign.service;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.stereotype.Service;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.client.RestTemplate;@FeignClient(value="spring-cloud-provide",fallback = HelloHystrixService.class)public interface HelloService {@RequestMapping(value="/hello/gethello",method = RequestMethod.GET)String sayHelloFromProvider(@RequestParam(value ="name") String name);}
创建一个回调的类HelloHystrixService
packagecom.brimen.springcloudconsumerfeign.service;importorg.springframework.stereotype.Component;@ComponentpublicclassHelloHystrixServiceimplementsHelloService{@OverridepublicStringsayHelloFromProvider(String name){return"hi,"+name+",sorry,error!"; }}
第三步:启动程序并访问
依次启动spring-cloud-eureka、spring-cloud-provide和spring-cloud-consumer-feign
访问spring-cloud-consumer-feign的接口:
http://localhost:8084/hello/gethello
结果如下:
结果:在spring-cloud-provide能访问的情况下,能够正常访问到接口并收到数据
第四步:将spring-cloud-provide服务关闭
重新访问http://localhost:8084/hello/gethello,发现断路器已经起作用,调用的是HelloHystrixService里面的回调方法。
参考:https://blog.csdn.net/qq_24630433/article/details/87926922http://blog.didispace.com/springcloud2/
https://mp.weixin.qq.com/s/Y9RJMVD3QnJv3DiB-chKDw