前言

欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud。

本系列适合有一定Java以及SpringBoot基础的同学阅读。

每篇文章末尾都附有本文对应的Github源代码,方便同学调试。

Github仓库地址:

https://github.com/qqxx6661/springcloud_for_noob

菜鸟SpringCloud实战入门系列

你可以通过以下两种途径查看菜鸟SpringCloud实战入门系列

  • 关注我的公众号:Rude3Knife 点击公众号下方:技术推文——SpringCloud
  • 菜鸟SpringCloud实战入门专栏导航页(CSDN)

前文回顾:

  • [菜鸟SpringCloud入门]第一章:构建多模块的Maven项目+创建注册中心Eureka子模块
  • [菜鸟SpringCloud入门]第二章:创建服务提供者并在Eureka进行注册
  • [菜鸟SpringCloud入门]第三章:将Eureka改造为高可用集群
  • [菜鸟SpringCloud入门]第四章:远程调用服务实战
  • …更多文章请查看上方:菜鸟SpringCloud入门实战专栏导航页

实战版本

  • SpringBoot:2.0.3.RELEASE
  • SpringCloud:Finchley.RELEASE

-----正文开始-----

熔断器Hystrix的使用

熔断器的概念

关于熔断器的解释,这里引用一大段:

熔断器适用于实现快速失败,如果它在一段时间内侦测到许多类似的错误,会强迫其以后的多个调用快速失败,不再访问远程服务器,从而防止应用程序不断地尝试执行可能会失败的操作,使得应用程序继续执行而不用等待修正错误,或者浪费CPU时间去等到长时间的超时产生。熔断器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。

熔断器模式就像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定使用允许操作继续,或者立即返回错误。 熔断器开关相互转换的逻辑如下图:

熔断器就是保护服务高可用的最后一道防线。

Hystrix特性

1.断路器机制

断路器很好理解, 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.

2.Fallback

Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存.

3.资源隔离

在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池. 例如调用产品服务的Command放入A线程池, 调用账户服务的Command放入B线程池. 这样做的主要优点是运行环境被隔离开了. 这样就算调用服务的代码存在bug或者由于其他原因导致自己所在线程池被耗尽时, 不会对系统的其他服务造成影响. 但是带来的代价就是维护多个线程池会对系统带来额外的性能开销. 如果是对性能有严格要求而且确信自己调用服务的客户端代码不会出问题的话, 可以使用Hystrix的信号模式(Semaphores)来隔离资源.

使用Feign Hystrix

依然使用上一章建立的子模块:Service-Feign

pom文件不需要变化,因为spring-cloud-starter-openfeign已经自带了Hystrix。

修改配置文件application.yml,增加如下:

feign:hystrix:enabled: true

在我这里,由于Springboot使用了2.0.3,引入的是openfeign,所以出现了:

起初以为这条指令无法生效,折腾了之后才发现是生效的。

推测是openfeign的问题,不是spring boot 1.X的spring-cloud-starter-feign,IDEA判断失误了。

接着新建类ServiceHiHystrix继承ServiceHi接口,里面实现了失败下的返回信息:

import org.springframework.stereotype.Component;@Component
public class ServiceHiHystrix implements ServiceHi {@Overridepublic String sayHiFromServiceHi(String name) {return "hello" + name +", this message send failed";}
}

更改ServiceHi接口,添加上fallback类为刚才新建的类:

@FeignClient(value = "service-hi", fallback = ServiceHiHystrix.class)

大功告成,启动server-feign,eureka-hi和eureka测试:

打开:http://localhost:8765/hello/rude3knife

接着,关掉服务提供者eureka-hi,来模拟服务宕机的情况,重新访问:http://localhost:8765/hello/rude3knife

返回了新建的错误信息。

可视化熔断器监控Hystrix Dashboard和Turbine

Hystrix Dashboard

Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数据。

我们只需要在上一章中的server-feign模块继续修改,因为上一章已经在该模块加了熔断器。

首先添加依赖:

<dependency><groupId>org.springframework.cloud</groupId><!--spring boot 1.X:spring-cloud-starter-hystrix--><artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><!--spring boot 1.X:spring-cloud-starter-hystrix-dashboard--><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

启动类修改:

@EnableHystrixDashboard
@EnableCircuitBreaker

启动工程访问:

http://localhost:8765/hystrix,将会看到如下界面:

图中会有一些提示:

  • Cluster via Turbine (default cluster): http://turbine-hostname:port/turbine.stream
  • Cluster via Turbine (custom cluster): http://turbine-hostname:port/turbine.stream?cluster=[clusterName]
  • Single Hystrix App: http://hystrix-app:port/hystrix.stream

大概意思就是如果查看默认集群使用第一个url,查看指定集群使用第二个url,单个应用的监控使用最后一个,我们暂时只演示单个应用的所以在输入框中输入: http://localhost:8765/hystrix.stream ,输入之后点击 monitor,进入页面。

如果没有请求会先显示Loading …,访问http://localhost:9001/hystrix.stream 也会不断的显示ping。

请求服务http://localhost:8765/hello/rude3knife,就可以看到监控的效果了,首先访问http://localhost:8765/hystrix.stream,显示如下:

出错了!

随机谷歌了下问题,网友给出了问题解决方案:

https://blog.csdn.net/ddxd0406/article/details/79643059

答主通过查看源码后给出的解决方案是:

评论区给出更为方便且优雅的方案:

在配置文件中加入management.endpoints.web.exposure.include=*,将端口暴露就不需要声明bean了,访问地址要变一下/actuator/hystrix.stream

于是我们在yml中加入:

# 熔断器DashBoard: actuator在boot2.0调整后开关web端点的配置,*代表开启所有
management:endpoints:web:exposure:include: "*"

重新运行模块,然后在网址一栏输入:

http://localhost:8765/actuator/hystrix.stream

页面会不停显示Loading,不用慌,不显示Unable to connect to Command Metric Stream.了。显示Loading是因为因为还没有请求过来。

之后我们尝试发一次请求,在地址栏对server-feign的8765端口发送请求:

http://localhost:8765/hello/1232312

再来看之前的页面,大功告成。

到此单个应用的熔断监控已经完成。

Turbine

但是只使用Hystrix Dashboard的话, 你只能看到单个应用内的服务信息, 这明显不够. 我们需要一个工具能让我们汇总系统内多个服务的数据并显示到Hystrix Dashboard上, 这个工具就是Turbine.

在复杂的分布式系统中,相同服务的节点经常需要部署上百甚至上千个,很多时候,运维人员希望能够把相同服务的节点状态以一个整体集群的形式展现出来,这样可以更好的把握整个系统的状态。

注意:

为了演示Turbine,在这里重新新建一个子模块,名为hystrix-dashboard-turbine,创建步骤请看之前的第一章。

创建新模块作为单独的监控节点模块,是因为演示dashboard的时候是耦合在了server-feign中,而Turbine需要同时监控多个服务消费者,把他耦合在一个消费者里显得不合时宜。

创建后,pom.xml中引入:

<dependency><groupId>org.springframework.cloud</groupId><!--spring boot 1.X:spring-cloud-starter-hystrix-dashboard--><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-netflix-turbine</artifactId>
</dependency>

启动类中@EnableTurbine和@EnableHystrixDashboard:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.turbine.EnableTurbine;@SpringBootApplication
@EnableTurbine
@EnableHystrixDashboard
public class HystrixDashboardTurbineApplication {public static void main(String[] args) {SpringApplication.run(HystrixDashboardTurbineApplication.class, args);}}

yml中:

server:# 服务端口号port: 8767
spring:application:# 服务名,即serviceIdname: hystrix-dashboard-turbine
eureka:client:serviceUrl:# 安全认证的服务注册中心地址defaultZone: http://localhost:8761/eureka
# 熔断器turbine
turbine:aggregator:cluster-config: defaultcluster-name-expression: new String("default")app-config: SERVICE-FEIGN, SERVICE-FEIGN-2

代码重点:

  • 新模块端口号为:8767
  • turbine.appConfig :配置Eureka中的serviceId列表,表明监控哪些服务(这里指定为SERVICE-FEIGN, SERVICE-FEIGN-2,稍后说)
  • turbine.aggregator.clusterConfig :指定聚合哪些集群,多个使用”,”分割,默认为default。可使用http://…/turbine.stream?cluster={clusterConfig之一}访问
  • turbine.clusterNameExpression :
    • clusterNameExpression指定集群名称,默认表达式appName;此时:turbine.aggregator.clusterConfig需要配置想要监控的应用名称;
    • 当clusterNameExpression: default时,turbine.aggregator.clusterConfig可以不写,因为默认就是default;
    • 当clusterNameExpression: metadata[‘cluster’]时,假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC,则需要配置,同时turbine.aggregator.clusterConfig: ABC

完成这些步骤后,我们还需要调整下服务提供者,我们需要两个服务提供者同时运行。

将8765(SERVICE-FEIGN)的服务提供者改为8766,名称改为:SERVICE-FEIGN-2,运行起来,别忘了在运行设置中设置允许多个实例运行。修改后的SERVICE-FEIGN的yml是:

server:# 服务端口号port: 8766
spring:application:# 服务名,即serviceIdname: service-feign-2
eureka:client:serviceUrl:# 安全认证的服务注册中心地址defaultZone: http://localhost:8761/eureka
# 熔断器设置
feign:hystrix:enabled: true
# 熔断器DashBoard: actuator在boot2.0调整后开关web端点的配置,*代表开启所有
management:endpoints:web:exposure:include: "*"

运行后结构如图:


我们访问:

访问 http://localhost:8767/turbine.stream

可以看到ping的信息流,这时说明8767正在不断ping指定的两个服务

进行图形化监控查看,输入:http://localhost:8767/hystrix ,返回酷酷的小熊界面,输入: http://localhost:8767/turbine.stream ,然后点击 Monitor Stream ,可以看到出现了监控列表:

咦?为啥只有一个监控呢,说好的聚合监控列表呢。

这里有个坑,或者说是理解上的误区:

监控不同的服务熔断,首先得是不同的rpc调用,也就是消费者的熔断函数要是两个不同的,或者,消费者去调用的是两个不同的服务提供者!这样才会有多个监控表。不然,有何意义?

想明白这一步,你就应该知道怎么把多个表弄出来了。

你需要让消费者有一个:

  • 新的消费目标(新的服务提供者)
  • 或者是一个新的消费熔断器。

修改server-feign子模块

  1. ServiceHi接口的调用变为sayHiFromServiceHi2,value也指向另一个服务提供者service-hi-2 (新的消费目标(新的服务提供者))
@FeignClient(value = "service-hi-2", fallback = ServiceHiHystrix.class)
public interface ServiceHi {/*** <p>通过Feign伪Http客户端调用service-hi提供的服务</p>* @author hanchao 2018/5/19 17:59**/@GetMapping("/hi/{name}")String sayHiFromServiceHi2(@PathVariable(value = "name") String name);
}
  1. 修改熔断器ServiceHiHystrix (新的消费熔断器)
@Component
public class ServiceHiHystrix implements ServiceHi {@Overridepublic String sayHiFromServiceHi2(String name) {return "hello" + name +", this message send failed. By Hystrix.";}
}
  1. 当然,随之更改的是HelloController,需要改为return serviceHi.sayHiFromServiceHi2
@RestController
public class HelloController {/** 注入服务"service-hi"的Feign客户端ServiceHi */@Autowiredprivate ServiceHi serviceHi;/*** 调用Feign客户端提供的服务,自带负载均衡* @param name* @return*/@GetMapping("/hello/{name}")public String sayHi(@PathVariable String name){//调用Feign客户端ScheduleServiceHi的接口return serviceHi.sayHiFromServiceHi2(name);}
}

这样改完后,重启这个8766的服务消费者

结构依然不变:

我们得到了:

  • 上方两排:不同的熔断器
  • 下方两排:不同的消费提供者

这里确实比较难理解哈,坑了我好久。

本章代码

https://github.com/qqxx6661/springcloud_for_noob/tree/master/05-hystrix-dashboard-turbine

参考

springcloud(四):熔断器Hystrix

http://www.ityouknow.com/springcloud/2017/05/16/springcloud-hystrix.html

springcloud(五):熔断监控Hystrix Dashboard和Turbine

http://www.ityouknow.com/springcloud/2017/05/18/hystrix-dashboard-turbine.html

-----正文结束-----

菜鸟SpringCloud实战入门专栏全导航:通过以下两种途径查看

  • 关注我的公众号:Rude3Knife 点击公众号下方:技术推文——SpringCloud
  • 菜鸟SpringCloud实战专栏(CSDN)

关注我

我是蛮三刀把刀,后端开发。主要关注后端开发,数据安全,爬虫等方向。

来微信和我聊聊:yangzd1102

Github个人主页:

https://github.com/qqxx6661

原创博客主要内容

  • Java知识点复习全手册
  • Leetcode算法题解析
  • 剑指offer算法题解析
  • Python爬虫相关技术实战
  • 后端开发相关技术实战
  • SpringCloud实战

同步更新公众号及以下全部博客:

1. Csdn

http://blog.csdn.net/qqxx6661

2. 知乎

https://www.zhihu.com/people/yang-zhen-dong-1/

3. 掘金

https://juejin.im/user/5b48015ce51d45191462ba55

4. 简书

https://www.jianshu.com/u/b5f225ca2376

个人公众号:Rude3Knife

如果文章对你有帮助,不妨收藏起来并转发给您的朋友们~

[菜鸟SpringCloud实战入门]第五章:熔断器Hystrix的使用 + 可视化监控Hystrix Dashboard和Turbine相关推荐

  1. [菜鸟SpringCloud实战入门]第七章:配置中心客户端主动刷新机制 + 配置中心服务化和高可用改造...

    前言 欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud. 本系列适合有一定Java以及Sp ...

  2. [菜鸟SpringCloud实战入门]第九章:服务网关Zuul体验

    前言 欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud. 本系列适合有一定Java以及Sp ...

  3. Python--Redis实战:第五章:使用Redis构建支持程序:第2节:计数器和统计数据...

    上一篇文章:Python--Redis实战:第五章:使用Redis构建支持程序:第1节:使用Redis来记录日志 下一篇文章:Python--Redis实战:第五章:使用Redis构建支持程序:第3节 ...

  4. core组件进阶(Opencv3编程入门 第五章) 第四节 图像对比度亮度调整

    core组件进阶(Opencv3编程入门 第五章) 第四节 图像对比度亮度调整 #include <opencv2/core/core.hpp> #include <opencv2/ ...

  5. 《GitHub入门与实战》第五章

    第五章 详细解说GitHub的功能 注意: 随着版本的更新,github上的界面也随之改变了很多,但是功能还是不变的,只是放在了不同的位置上.   GitHub 为实现社会化编程提供了诸多功能. 5. ...

  6. springCloud Finchley 实战入门(基于springBoot 2.0.3)【六 Hystrix 仪表盘】

    Hystrix仪表盘 通过上一篇我们已经成功的实现了spring cloud对Hystrix的整合了.除此之外,spring cloud还完美的整合了Hystrix的仪表盘组件Hystrix Dash ...

  7. 【Java笔记】Java开发实战经典 - 第五章

    ===第五章 面向对象(基础篇) 面向对象的程序设计有封装性.继承性.多态性3个主要特征: 类是抽象的代表共性,对象是具体的个体,属性是描述对象的信息,方法是对象的行为: 类由属性和方法组成,属性就是 ...

  8. 【数据可视化】第五章—— 基于PyEcharts的数据可视化

    文章目录 1. pyecharts数据可视化介绍 2.pyecharts安装与使用 3.全局配置项和系列配置项 3.1 全局配置项 3.1.1 基本元素配置项 3.1.2 坐标轴配置项 3.1.3 原 ...

  9. 《Java8实战》-第五章读书笔记(使用流Stream-02)

    付诸实战 在本节中,我们会将迄今学到的关于流的知识付诸实践.我们来看一个不同的领域:执行交易的交易员.你的经理让你为八个查询找到答案. 找出2011年发生的所有交易,并按交易额排序(从低到高). 交易 ...

最新文章

  1. 只需一行代码,你的纯文本秒变 Markdown
  2. Nat. Ecol. Evol.:不想当化学家的物理学家不是好的生物学家
  3. 面向对象深入:继承03——抽象类
  4. 音视频技术开发周刊 | 221
  5. 【转自CodeSheep】程序猿好书推荐
  6. java程序中可以如何异常处理?_如何处理罗茨鼓风机在运行过程中出现异常噪音和叶片的运行特性...
  7. 114. Flatten Binary Tree to Linked List【Medium】【将给定的二叉树转化为“只有右孩子节点”的链表(树)】...
  8. 【转载】随机游走及马尔科夫链(本体映射相关)
  9. php设计模式课程---4、观察者模式的好处是什么
  10. 10.企业应用架构模式 --- 数据源架构模式
  11. python的代码保存到文档中 打不开怎么办_Python 制作网页打不开 直接跳到打开或者保存文件...
  12. python笔记小白入门_python小白入门基础(七:集合与字典)
  13. w ndows7旗舰版网卡驱动,Win7网卡驱动64位离线安装包 免费版
  14. 如何将几个pdf合并成一个pdf?
  15. 淘宝API如何获取商品详情信息|sku|价格|店铺|优惠券|运费信息,淘宝商品详情API接口
  16. docker操作记录-5
  17. R语言 substitute
  18. 2022年亚太杯数学建模竞赛ABC题
  19. InnoDB关键特性之插入缓冲
  20. 应用层与HTTP协议

热门文章

  1. 大数据24小时:阿里95亿美元全资收购饿了么,腾讯无人车首次公开亮相北京四环
  2. 【Rails】TDD-测试驱动开发
  3. java object toarray,Object[] toArray()
  4. Java经典实例(第二版)各种工具
  5. 2020高人气小巧真无线蓝牙耳机推荐,无线蓝牙耳机选购指南
  6. 中国计算机硬件现状及其发展趋势,中国计算机硬件现状及其发展趋势
  7. NODE.JS如何开发短信接口发送短信验证码/短信通知demo示例
  8. 广州市工业和信息化局关于组织开展信息技术应用创新行业适配中心入库征集工作的通知
  9. Python添加mysql数据:insert_to_db.py
  10. 华为荣耀android是什么系统,华为荣耀Android4.0系统正式发布