JAVA语言:详解Spring Cloud 熔断机制--断路器
龚超 2018-06-25 来源 : 阅读 3522 评论 0

摘要:本文主要向大家介绍了JAVA语言的详解Spring Cloud 熔断机制--断路器,通过具体的实例让大家了解,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言的详解Spring Cloud 熔断机制--断路器,通过具体的实例让大家了解,希望对大家学习JAVA语言有所帮助。

在分布式环境下,特别是微服务结构的分布式系统中, 一个软件系统调用另外一个远程系统是非常普遍的。这种远程调用的被调用方可能是另外一个进程,或者是跨网路的另外一台主机, 这种远程的调用和进程的内部调用最大的区别是,远程调用可能会失败,或者挂起而没有任何回应,直到超时。更坏的情况是, 如果有多个调用者对同一个挂起的服务进行调用,那么就很有可能的是一个服务的超时等待迅速蔓延到整个分布式系统,引起连锁反应, 从而消耗掉整个分布式系统大量资源。最终可能导致系统瘫痪。

断路器(Circuit Breaker)模式就是为了防止在分布式系统中出现这种瀑布似的连锁反应导致的灾难。

一旦某个电器出问题,为了防止灾难,电路的保险丝就会熔断。断路器类似于电路的保险丝, 实现思路非常简单,可以将需要保护的远程服务嗲用封装起来,在内部监听失败次数, 一旦失败次数达到某阀值后,所有后续对该服务的调用,断路器截获后都直接返回错误到调用方,而不会继续调用已经出问题的服务, 从而达到保护调用方的目的, 整个系统也就不会出现因为超时而产生的瀑布式连锁反应。

1. 基本模式


上图是断路器(Curcuit Breaker)的结构,它有两个基本状态(close和open)和一个基本trip动作:

close状态下, client向supplier发起的服务请求, 直接无阻碍通过断路器, supplier的返回值接直接由断路器交回给client.

open状态下,client向supplier发起的服务请求后,断路器不会将请求转到supplier, 而是直接返回client, client和supplier之间的通路是断的

trip: 在close状态下,如果supplier持续超时报错, 达到规定的阀值后,断路器就发生trip, 之后断路器状态就会从close进入open.

2. 扩展模式

基本的断路器模式下,保证了断路器在open状态时,保护supplier不会被调用, 但我们还需要额外的措施可以在supplier恢复服务后,可以重置断路器。一种可行的办法是断路器定期探测supplier的服务是否恢复, 一但恢复, 就将状态设置成close。断路器进行重试时的状态为半开(half-open)状态。


3. 断路器的使用场合:

一个supplier一般很稳定,如果一旦故障发生后, 检查和恢复需要的时间比较长,通常无法短时间内快速修复的,那么这种服务比较适合采用断路器模式。否则很可能导致ping-pong效应。

3. 断路器不适合的场合:

为了防止一个应用程序试图调用一个远程服务或访问共享资源,如果??该操作是极有可能失败, 这种模式可能不适合。

对于处理中的应用程序访问本地专用资源,例如在存储器内数据结构。在这种环境下通常也不适合,使用断路器只会增加系统开销。

下面直接介绍Spring Cloud的断路器如何使用。

SpringCloud Netflix实现了断路器库的名字叫Hystrix. 在微服务架构下,通常会有多个层次的服务调用.下面是微服架构下, 浏览器端通过API访问后台微服务的一个示意图:


一个微服务的超时失败可能导致瀑布式连锁反映,下图中,Hystrix通过自主反馈实现的断路器,防止了这种情况发生。


图中的服务B因为某些原因失败,变得不可用,所有对服务B的调用都会超时。当对B的调用失败达到一个特定的阀值(5秒之内发生20次失败是Hystrix定义的缺省值), 链路就会被处于open状态, 之后所有所有对服务B的调用都不会被执行, 取而代之的是由断路器提供的一个表示链路open的Fallback消息. Hystrix提供了相应机制,可以让开发者定义这个Fallbak消息.

open的链路阻断了瀑布式错误, 可以让被淹没或者错误的服务有时间进行修复。这个fallback可以是另外一个Hystrix保护的调用, 静态数据,或者合法的空值. Fallbacks可以组成链式结构,所以,最底层调用其它业务服务的第一个Fallback返回静态数据.

下面,进入正题,在之前的两HELLO WORLD服务集群中加入断路器, 防止其中一个Hello world挂掉后, 导致系统发生连锁超时失败。

1. 在maven工程(前面章节中介绍的Ribbon或者Feign工程)的pom.xml中添加hystrix库支持断路器


org.springframework.cloud

spring-cloud-starter-hystrix


复制代码

2.在Ribbon应用中使用断路器

1). 在Spring Boot启动类上添加@EnableCircuitBreaker注解


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


复制代码

2). 用@HystrixCommand注解标注访问服务的方法


@Service
public class HelloService {
@Autowired RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "serviceFailure")
public String getHelloContent() {
return restTemplate.getForObject("//SERVICE-HELLOWORLD/",String.class);
}
public String serviceFailure() {
return "hello world service is not available !";
}
}

复制代码

@HystrixCommand注解定义了一个断路器,它封装了getHelloContant()方法, 当它访问的SERVICE-HELLOWORLD失败达到阀值后,将不会再调用SERVICE-HELLOWORLD, 取而代之的是返回由fallbackMethod定义的方法serviceFailure()。@HystrixCommand注解定义的fallbackMethod方法,需要特别注意的有两点:

第一, fallbackMethod的返回值和参数类型需要和被@HystrixCommand注解的方法完全一致。否则会在运行时抛出异常。比如本例中,serviceFailure()的返回值和getHelloContant()方法的返回值都是String。

第二, 当底层服务失败后,fallbackMethod替换的不是整个被@HystrixCommand注解的方法(本例中的getHelloContant), 替换的只是通过restTemplate去访问的具体服务。可以从中的system输出看到, 即使失败,控制台输出里面依然会有“call SERVICE-HELLOWORLD”。

启动eureka服务,只启动两个Helloworld服务,然后中断其中一个(模拟其中一个微服务挂起),访问//localhost:8901/然后刷新, 由于有负载均衡可以看到以下两个页面交替出现。可以看到第二个被挂起的服务,被定义在Ribbon应该里面的错误处理方法替换了。

 

4. 在Feign应用中使用断路器

1). Feign内部已经支持了断路器,所以不需要想Ribbon方式一样,在Spring Boot启动类上加额外注解

2). 用@FeignClient注解添加fallback类, 该类必须实现@FeignClient修饰的接口。


@FeignClient(name = "SERVICE-HELLOWORLD", fallback = HelloWorldServiceFailure.class)
public interface HelloWorldService {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String sayHello();
}

复制代码

3). 创建HelloWorldServiceFailure类, 必须实现被@FeignClient修饰的HelloWorldService接口。注意添加@Component或者@Service注解,在Spring容器中生成一个Bean


@Component
public class HelloWorldServiceFailure implements HelloWorldService {
@Override
public String sayHello() {
System.out.println("hello world service is not available !");
return "hello world service is not available !";
}
}

复制代码

4). Spring Cloud之前的Brixton版本中,Feign是缺省是自动激活了断路器的,但最近的Dalston版本已经将缺省配置修改为禁止。

原因参见: https://github.com/spring-cloud/spring-cloud-netflix/issues/1277, 这一点要注意。所以要在Feign中使用断路器, 必须在application.yml中添加如下配置:


feign:

hystrix:

enabled: true

复制代码

5). 启动Feign应用, 访问//localhost:8902/hello, 可以一看到和Ribbon一样的效果。

参考://projects.spring.io/spring-cloud/spring-cloud.html#_circuit_breaker_hystrix_clients

//projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign-hystrix

希望对JAVA有兴趣的朋友有所帮助。了解更多内容,请关注职坐标编程语言JAVA频道!

本文由 @职坐标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论
本文作者 联系TA

擅长针对企业软件开发的产品设计及开发的细节与流程设计课程内容。座右铭:大道至简!

  • 370
    文章
  • 23384
    人气
  • 87%
    受欢迎度

已有23人表明态度,87%喜欢该老师!

进入TA的空间
求职秘籍 直通车
  • 索取资料 索取资料 索取资料
  • 答疑解惑 答疑解惑 答疑解惑
  • 技术交流 技术交流 技术交流
  • 职业测评 职业测评 职业测评
  • 面试技巧 面试技巧 面试技巧
  • 高薪秘笈 高薪秘笈 高薪秘笈
TA的其他文章 更多>>
WEB前端必须会的基本知识题目
经验技巧 93% 的用户喜欢
Java语言中四种遍历List的方法总结(推荐)
经验技巧 91% 的用户喜欢
Java语言之SHA-256加密的两种实现方法详解
经验技巧 75% 的用户喜欢
java语言实现把两个有序数组合并到一个数组的实例
经验技巧 75% 的用户喜欢
通过Java语言代码来创建view的方法
经验技巧 80% 的用户喜欢
其他海同师资 更多>>
吕益平
吕益平 联系TA
熟悉企业软件开发的产品设计及开发
孔庆琦
孔庆琦 联系TA
对MVC模式和三层架构有深入的研究
周鸣君
周鸣君 联系TA
擅长Hadoop/Spark大数据技术
范佺菁
范佺菁 联系TA
擅长Java语言,只有合理的安排和管理时间你才能做得更多,行得更远!
金延鑫
金延鑫 联系TA
擅长与学生或家长及时有效沟通
经验技巧30天热搜词 更多>>

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程