对断路器模式不太清楚的话,可以参看另一篇博文:断路器(Curcuit Breaker)模式,下面直接介绍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库支持断路器

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

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("http://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服务,然后中断其中一个(模拟其中一个微服务挂起),访问http://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应用, 访问http://localhost:8902/hello, 可以一看到和Ribbon一样的效果。

上一篇:Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务

下一篇:Spring Cloud 入门教程(八): 断路器指标数据监控Hystrix Dashboard

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

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

Spring Cloud 入门教程(七): 熔断机制 -- 断路器的更多相关文章

  1. Spring Cloud 入门教程(八): 断路器指标数据监控Hystrix Dashboard 和 Turbine

    1. Hystrix Dashboard (断路器:hystrix 仪表盘)  Hystrix一个很重要的功能是,可以通过HystrixCommand收集相关数据指标. Hystrix Dashboa ...

  2. Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务

    首先简单解释一下什么是声明式实现? 要做一件事, 需要知道三个要素,where, what, how.即在哪里( where)用什么办法(how)做什么(what).什么时候做(when)我们纳入ho ...

  3. Spring Cloud 入门教程 - 搭建配置中心服务

    简介 Spring Cloud 提供了一个部署微服务的平台,包括了微服务中常见的组件:配置中心服务, API网关,断路器,服务注册与发现,分布式追溯,OAuth2,消费者驱动合约等.我们不必先知道每个 ...

  4. Spring Cloud 入门教程(十):和RabbitMQ的整合 -- 消息总线Spring Cloud Netflix Bus

    在本教程第三讲Spring Cloud 入门教程(三): 配置自动刷新中,通过POST方式向客户端发送/refresh请求, 可以让客户端获取到配置的最新变化.但试想一下, 在分布式系统中,如果存在很 ...

  5. Spring Cloud 入门教程(九): 路由网关zuul

    在微服务架构中,需要几个关键的组件,服务注册与发现.服务消费.负载均衡.断路器.智能路由.配置管理等,由这几个组件可以组建一个简单的微服务架构.客户端的请求首先经过负载均衡(zuul.Ngnix),再 ...

  6. Spring Cloud 入门教程(五): Ribbon实现客户端的负载均衡

    接上节,假如我们的Hello world服务的访问量剧增,用一个服务已经无法承载, 我们可以把Hello World服务做成一个集群. 很简单,我们只需要复制Hello world服务,同时将原来的端 ...

  7. 利用Spring Cloud实现微服务- 熔断机制

    1. 熔断机制介绍 在介绍熔断机制之前,我们需要了解微服务的雪崩效应.在微服务架构中,微服务是完成一个单一的业务功能,这样做的好处是可以做到解耦,每个微服务可以独立演进.但是,一个应用可能会有多个微服 ...

  8. Spring Cloud 入门教程(一): 服务注册

    1.  什么是Spring Cloud? Spring提供了一系列工具,可以帮助开发人员迅速搭建分布式系统中的公共组件(比如:配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁 ...

  9. Spring Cloud 入门教程(二): 配置管理

    使用Config Server,您可以在所有环境中管理应用程序的外部属性.客户端和服务器上的概念映射与Spring Environment和PropertySource抽象相同,因此它们与Spring ...

随机推荐

  1. Linux 项目上线管理 MAVEN + expect 一台机器管理所有机器的应用程序

    一.目的 在一台服务器上面管理所有机器的应用程序. 设想是通过一条命令能够知道所有应用程序是否running 如果not running 查看具体项目的log 跟踪具体原因,程序问题汇报相关负责人 二 ...

  2. 理解 docker 容器中的 uid 和 gid

    默认情况下,容器中的进程以 root 用户权限运行,并且这个 root 用户和宿主机中的 root 是同一个用户.听起来是不是很可怕,因为这就意味着一旦容器中的进程有了适当的机会,它就可以控制宿主机上 ...

  3. C#如何发送邮件

    准备工作: 1.开启Smtp服务 2.如果邮件设置中有“客户端授权码"(以163邮箱为例,有的邮箱不需要),需要开启“客户端授权码" 发送邮件: using (MailMessag ...

  4. .NET Http请求

    声明:本代码只是我使用的网络请求方式的封装,大家如果有其他的可以一起讨论讨论.    本代码可以在.NET 与.NET CORE的平台下无须做任何改动(除非手动加一些必要的引用,resharper会有 ...

  5. 手机端input[type=date]的placeholder不起作用

    <div class="input clearfix"> <label class="fl">起始日期</label> &l ...

  6. 仿9GAG制作过程(二)

    有话要说: 这次准备讲述用python爬虫以及将爬来的数据存到MySQL数据库的过程,爬的是煎蛋网的无聊图. 成果: 准备: 下载了python3.7并配置好了环境变量 下载了PyCharm作为开发p ...

  7. 五、RemoteViews

    RemoteViews表示的是一个View结构,它可以在其他进程中显示.RemoteViews在Android中的使用场景有两种:通知栏和桌面小部件. 1.RemoteViews的应用 RemoteV ...

  8. leetcode-48.旋转图像

    leetcode-48.旋转图像 point: 数组 题意 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维 ...

  9. SCSS 在项目中的运用

    最后一段时间一直在做一些网站或是CMS的项目,想用bootstrap,但是,设计那哥们说了,用什么都行,就不能用bootstrap,我去了个..... 无语中,逼着自己写.说实话,就是用bootstr ...

  10. selenium-历史(一)

    简介 Selenium是ThoughtWorks公司研发的一个强大的基于浏览器的开源自动化测试工具,它通常用来编写web应用的自动化测试.早期也即Selenium1.x时期主要使用Selenium R ...