在上两篇文章中讲了,服务提供者 Eureka + 服务消费者 Feign,服务提供者 Eureka + 服务消费者(rest + Ribbon),本篇文章结合,上两篇文章中代码进行修改加入 断路器监控(Hystrix Dashboard)

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

针对上述问题,在Spring Cloud Hystrix中实现了线程隔离、断路器等一系列的服务保护功能。它也是基于Netflix的开源框架 Hystrix实现的,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备了服务降级、服务熔断、线程隔离、请求缓存、请求合并以及服务监控等强大功能。

什么是断路器

断路器模式源于Martin Fowler的Circuit Breaker一文。“断路器”本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,“断路器”能够及时的切断故障电路,防止发生过载、发热、甚至起火等严重后果。

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

断路器示意图

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

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

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

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

准备工作

在开始加入断路器之前,我们先拿之前两篇博客,构建的两个微服务代码为基础,进行下面的操作

建议先阅读以下两篇文章

Spring Cloud(四) 服务提供者 Eureka + 服务消费者 Feign
Spring Cloud(三) 服务提供者 Eureka + 服务消费者(rest + Ribbon)

Eureka Service

导入第三篇文章中的项目:作为服务注册中心

spring-cloud-eureka-service

Eureka Provider

导入第三篇文章中的项目:作为服务的提供者

spring-cloud-eureka-provider-1
spring-cloud-eureka-provider-2
spring-cloud-eureka-provider-3

Ribbon Hystrix

在 Ribbon中使用断路器

修改项目

复制 spring-cloud-ribbon-consumer 项目,修改名称为spring-cloud-ribbon-consumer-hystrix

添加依赖

在项目pom 加上hystrix的依赖

<!-- hystrix 断路器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

服务注册

在程序的启动类 RibbonConsumerApplication 通过 @EnableHystrix 开启 Hystrix 断路器监控

package com.sc.robbin.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication { @LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
} public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApplication.class, args);
} }

消费提供者方法

修改 ConsumerController 类的,hello 方法,加上注解@HystrixCommand(fallbackMethod = "defaultStores") 该注解对该方法创建了熔断器的功能 ,并指定了defaultStores熔断方法,熔断方法直接返回了一个字符串, "feign + hystrix ,提供者服务挂了"

@HystrixCommand 表明该方法为hystrix包裹,可以对依赖服务进行隔离、降级、快速失败、快速重试等等hystrix相关功能 该注解属性较多,下面讲解其中几个

  • fallbackMethod 降级方法
  • commandProperties 普通配置属性,可以配置HystrixCommand对应属性,例如采用线程池还是信号量隔离、熔断器熔断规则等等
  • ignoreExceptions 忽略的异常,默认HystrixBadRequestException不计入失败
  • groupKey() 组名称,默认使用类名称
  • commandKey 命令名称,默认使用方法名
  • package com.sc.robbin.consumer;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; /**
    * 描述:调用提供者的 `home` 方法
    *
    * @author yanpenglei
    * @create 2017-12-05 18:53
    **/
    @RestController
    public class ConsumerController { @Autowired
    private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "defaultStores")
    @GetMapping(value = "/hello")
    public String hello() {
    return restTemplate.getForEntity("http://service-hi/", String.class).getBody();
    } public String defaultStores() {
    return "Ribbon + hystrix ,提供者服务挂了";
    }
    }
    测试断路器
    依次启动项目: spring-cloud-eureka-service
    spring-cloud-eureka-provider-1
    spring-cloud-eureka-provider-2
    spring-cloud-eureka-provider-3
    spring-cloud-ribbon-consumer-hystrix 启动该工程后,访问服务注册中心,查看服务是否都已注册成功:http://localhost:8761/
  • 此处只开启两个clien作为测试,

  • 通过开启热启动的方式把clien1 修改

    package com.sc.eureka;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController; @SpringBootApplication
    @EnableEurekaClient
    @RestController
    public class EurekaClientApplication { @Value("${server.port}")
    String port;
    @RequestMapping("/43")
    public String home() { return "Hello world ,port:" + port;
    }
    public static void main(String[] args) {
    SpringApplication.run(EurekaClientApplication.class, args);
    } }

    在此访问时,当方位client1时就出出现如下所示提示:


  • Feign Hystrix

    在 Feign中使用断路器

    修改项目

    复制spring-cloud-feign-consumer 项目,修改名称为spring-cloud-feign-consumer-hystrix

    添加依赖

    Feign是自带断路器的,如果在Dalston版本的Spring Cloud中,它没有默认打开。需要需要在配置文件中配置打开它,本项目我们是不需要打开的

  • feign:
    hystrix:
    enabled: true

服务注册

修改 HomeClient类 ,@FeignClient 注解,加上fallbackFactory指定新建的HystrixClientFallbackFactory 工厂类

在程序的启动类 RibbonConsumerApplication 通过 @EnableHystrix 开启 Hystrix

/**
* 描述: 指定这个接口所要调用的 提供者服务名称 "eureka-provider"
*
* @author yanpenglei
* @create 2017-12-06 15:13
**/
@FeignClient(value ="eureka-provider",fallbackFactory = HystrixClientFallbackFactory.class)
public interface HomeClient {
@GetMapping("/")
String consumer();
}

新加的类 HystrixClientFallbackFactory.java

/**
* 描述:
*
* @author yanpenglei
* @create 2017-12-07 20:37
**/
@Component
public class HystrixClientFallbackFactory implements FallbackFactory<HomeClient> {
@Override
public HomeClient create(Throwable throwable) {
return () -> "feign + hystrix ,提供者服务挂了";
}
}

然后就可以断路测试了。

Hystrix Dashboard

HD 简介

Hystrix Dashboard在微服务架构中为例保证程序的可用性,防止程序出错导致网络阻塞,出现了断路器模型。断路器的状况反应了一个程序的可用性和健壮性,它是一个重要指标。Hystrix Dashboard是作为断路器状态的一个组件,提供了数据监控和友好的图形化界面。

改造项目

复制项目 spring-cloud-ribbon-consumer-hystrix,修改名称 spring-cloud-ribbon-consumer-hystrix-dashboard 在它的基础上进行改造。Feign的改造和这一样。

pom的工程文件引入相应的依赖:

添加依赖

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

开启 HD

修改 RibbonConsumerApplication.java 类

在程序的入口RibbonConsumerApplication类,加上@EnableHystrix注解开启断路器,这个是必须的,并且需要在程序中声明断路点@HystrixCommand;加上@EnableHystrixDashboard注解,开启HystrixDashboard

package io.ymq.example.ribbon.consumer.hystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableHystrix
@EnableDiscoveryClient
@EnableHystrixDashboard
@SpringBootApplication
public class RibbonConsumerApplication {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApplication.class, args);
}
}

声明断路点

声明断路点 @HystrixCommand(fallbackMethod = "defaultStores")

package io.ymq.example.ribbon.consumer.hystrix;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* 描述:调用提供者的 `home` 方法
*
* @author yanpenglei
* @create 2017-12-05 18:53
**/
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "defaultStores")
@GetMapping(value = "/hello")
public String hello() {
return restTemplate.getForEntity("http://eureka-provider/", String.class).getBody();
}
public String defaultStores() {
return "feign + hystrix Dashboard ,提供者服务挂了";
}
}

@HystrixCommand 表明该方法为hystrix包裹,可以对依赖服务进行隔离、降级、快速失败、快速重试等等hystrix相关功能 该注解属性较多,下面讲解其中几个

  • fallbackMethod 降级方法
  • commandProperties 普通配置属性,可以配置HystrixCommand对应属性,例如采用线程池还是信号量隔离、熔断器熔断规则等等
  • ignoreExceptions 忽略的异常,默认HystrixBadRequestException不计入失败
  • groupKey() 组名称,默认使用类名称
  • commandKey 命令名称,默认使用方法名
  • 依次启动项目:

    spring-cloud-eureka-service
    spring-cloud-eureka-provider-1
    spring-cloud-eureka-provider-2
    spring-cloud-eureka-provider-3
    spring-cloud-ribbon-consumer-hystrix-dashboard

    启动该工程后,访问服务注册中心,查看服务是否都已注册成功:http://localhost:8761/

Hystrix Dashboard 监控

可以访问 http://127.0.0.1:9090/hystrix ,获取Hystrix Dashboard信息,默认最大打开5个终端获取监控信息,可以增加delay参数指定获取监控数据间隔时间

在界面依次输入:http://127.0.0.1:9000/hystrix.stream 、2000 、hello 点确定。可以访问以下,图形化监控页面

最新文章

  1. Imagenet tools install on windows
  2. 哈希 poj 2002
  3. 本机搭建外网web服务器
  4. Hession矩阵与牛顿迭代法
  5. Unity3D ShaderLab 简单的立方体图反射
  6. 解决Win10默认占用80端口
  7. FOJ 1858 Super Girl 单调队列
  8. mysql重连,连接丢失:The last packet successfully received from the server--转载
  9. C++中的数组和指针
  10. css3动画结束捕捉事件整理
  11. [区块链] 带你进入Bitcoin开发 - 环境搭建
  12. 20165311 《网络对抗技术》 Kali安装
  13. 本周HTML5的知识点
  14. 异常:Caused by: java.sql.SQLException: Field &#39;cust_id&#39; doesn&#39;t have a default value
  15. JavaScript 作用域、命名空间及闭包
  16. Maven的porfile与SpringBoot的profile结合使用详解
  17. jQuery懒加载插件 – jquery.lazyload.js简单调用
  18. PHP文件PHP代码及运行(适合PHP初学者)
  19. Linux 小知识翻译 - 「X Window系统」
  20. JS实现随机背景图片与图片大小变换的效果

热门文章

  1. Apache实现一台服务器上运行多个网站
  2. Java使用jxl写入Excel文件
  3. jeecg启动报错“com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server.”的解决办法
  4. jQuery.fn.extend与jQuery.extend的区别
  5. opengl球形网格生成
  6. HANA数据自助查询
  7. 解决 nginx 单点问题的方案【h】
  8. 最新 前程无忧java校招面经 (含整理过的面试题大全)
  9. shell 入门学习
  10. Unsupported major.minor version 52.0——解决