Hystrix断路器(五)
1.1.1 概念
大意是一个系统依赖30个微服务,假设每个微服务可用时间是99.99%,换算成整个系统就是99.99的30次方约99.7%可用时间,0.3%不可用。1亿的请求有30万失败。30天有2个多小时不能正常提供服务。
现实通常比这更糟糕。举个例子:假设我们在电商网站买东西,从下单到完成要依赖三个微服务:订单、支付、物流。遇上双11或618,客户的订单蜂拥而至,这时候物流微服务可能因为程序优化不好或者硬件资源不够而不能及时提供服务,如果因为物流的问题而导致客户无法下单,这到手的钱挣不到了就很可惜了。
这时候就可以对物流微服务进行熔断,暂时不调用,全力以赴把订单、支付给完成了。熬过去这段峰值,回过头来再处理物流的问题,反正钱已到手。不会因为一颗老鼠屎坏一锅汤。
Spring Cloud的断路器是Hystrix,两种使用方法,一种是直接使用Hystrix,一种是通过FeignClient。
1.1.2 微服务设计引发新的问题
微服务的设计,服务分散在多个服务器上,服务之间互相调用,要调用的服务由于跨网络跨服务器调用,响应速度明显比传统项目单机调用慢很多,甚至由于网络涌动的不稳定的现象发生导致调用超时;还有类似级联失败、雪崩效应(依赖的基础服务宕机,关联的服务导致失败甚至宕机,就像滚雪球一样层层失败。)
如何解决这类新的问题呢?传统的机制就是超时机制。
1.1.3 超时机制
良好的设计,在通过网络请求其他服务时,都必须设置超时时间。正常情况下,一个远程调用几十毫秒内返回。当要调用的服务不可用时或者网络问题,响应时间要等超时,如HttpClient几十秒才超时返回。通常,一次远程调用对应一个线程/进程,如果大量的线程/进程得不到释放,并且越积越多,服务资源就会被耗尽,从而导致资深服务不可用。所以必须为每个请求设置超时时间。
例如:我们熟悉的tomcat就有超时设计
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" acceptCount="500" maxThreads="400" />
但我们发现传统的超时设计时间都比较久,面对今天互联网时代,用户对性能的极致要求时间显得太久了?20秒,用户要求网页秒级响应,等20秒,用户只能跟你说byebye了,扭头去找别的提供商了。
特别像微服务这样基于多个服务,服务之间都是远程调用,如果一个服务长时间等待,用户体验会极差的,那怎么办呢?断路器模式应运而生。
1.1.4 熔断机制
家里电表都有个断路器(俗称电闸),当使用的电器很多,用电巨大(例如功率过大、短路等),当电流过载时,电路就会升温,甚至烧断电路,引起火灾。有了这个断路器,我们及时拉闸,就不会造成严重后果了。
断路器可以实现快速失败,如果它在一段时间内检测到许多失败,如超时,就会强迫其以后的多个调用快速失败,不再请求所依赖的服务,从而防止应用程序不断地尝试执行可能会失败的操作,这样应用程序可以继续执行而不用等待修正错误,或者浪费CPU时间去等待长时间的超时。断路器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。
断路器模式像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定使用允许操作继续,或者立即返回错误。
1.1.5 状态
断路器有三种状态:
1. 关闭:当访问没有问题时,断路器处于关闭未使用。
2. 打开:当访问开始出现异常,错误次数增多,达到阀值时就会打开断路器,这样服务直接访问断路器,断路器会再尝试访问,如果失败直接返回。
3. 半开:那服务一直走断路器,系统就没法用了,万一被调用的服务以及稳定了呢。断路器的优势就来了,过一定时间窗口后(若干秒)它就会自动分流一部分服务再去尝试访问之前失败的服务。如果继续失败,那就不再转发,如果一个成功立即关闭断路器。
1.1.6 结构图
当服务B不可用时,开发人员需要写一个Fallback快速失败响应。可以设置为一个固定的值或者一个空值。
Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入fallback代码。而首次请求往往会比较慢(因为Spring的懒加载机制,要实例化一些类),这个响应时间可能就大于1秒了。
1.1.7 小结
l 不是立即宣布死亡,而是设置阀值,超越阀值才宣布死亡
l 传统方式死亡了就不管了,可断路器超级厉害,“死了也不放过”。自带心跳机制,自动测试路径是否可用,如发现又“活了”,会自动恢复调用关系。这一切开发者都无需编写代码
这样的设计太牛了,考虑非常细致全面,可以说做到了极致。不可用时立即响应,可用时自动恢复。不是网络抖动下,就永远宣布其死亡。这样的设计思想非常适合网络这种不稳定的应用场景。
1.2 消费者实现Hystrix
1.2.1 创建Maven项目
1.2.2 pom.xml
增加hystrix依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.wood</groupId> <artifactId>spring-cloud</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.wood</groupId> <artifactId>consumer-hystrix</artifactId> <version>0.0.1-SNAPSHOT</version> <name>consumer-hystrix</name> <description>Demo project for Spring Boot</description> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- Feign依赖,声明式开发 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>LATEST</version> </dependency> <!-- Hystrix,Feign是基于Hystrix的,Hystrix下一章节会讲到 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>LATEST</version> </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> <version>LATEST</version> </dependency> </dependencies> </project>
1.2.3 导入hystrix支持
Spring cloud没有直接使用NetFlix开源的Hystrix,而使用的是javanica,javanica在Hystrix基础上利用反射和注解技术增强和简化了Hystrix的开发。
1.2.4 application.properties
server.port=8094spring.application.name=consumer-hystrixeureka.client.serviceUrl.defaultZone=http://localhost:6001/eureka# 定义根目录下日志级别logging.level.root=INFO# 放开 hystrix 、health、info 等功能management.endpoints.web.exposure.include="*"
1.2.5 EurekaServiceFeign.java
package com.wood.consumerhystrix.remote; import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod; /** * 这个接口相当于把原来的服务提供者项目当成一个Service类 **/@FeignClient(value="provider-user", fallback = UserFeignFallback.class)public interface EurekaServiceFeign {/** * Feign中没有原生的@GetMapping/@PostMapping/@DeleteMapping/@PutMapping * 要指定需要用method进行 * */ @RequestMapping(value="/hello/{name}",method=RequestMethod.GET) String hello(@PathVariable("name") String name); }
1.2.6 HelloController.java
package com.wood.consumerhystrix.controller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import com.wood.consumerhystrix.remote.EurekaServiceFeign;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController; @RestControllerpublic class HelloController { @Autowired private EurekaServiceFeign eurekaServiceFeign; /** * hystrix配合feign使用 * 当feign连接出现故障,就不会再去请求了,直接进入fallback * tip:默认开启了两个provider-user服务,每次访问时交替出现,feign自带负载均衡的功能 * 如果满足不了需求可以加上Ribbon来实现专业的负载均衡 * @RibbonClient(name="provider-user", configuration=RibbonRuleConfig.class) * */ @GetMapping("/hello/{name}")@ResponseBody @HystrixCommand(fallbackMethod = "helloFallback")public String hello(@PathVariable String name){return eurekaServiceFeign.hello(name); } // 对应上面的方法,参数必须一致当访问失败时,hystrix直接回调用此方法 public String helloFallback(String name) {return name + "\nhystrix配合feign使用,当feign连接出现故障,就不会再去请求了,直接进入fallback"; }}
1.2.7 HystrixRunApp.java
package com.wood.consumerhystrix; import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.hystrix.EnableHystrix;import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;import org.springframework.cloud.openfeign.EnableFeignClients;import org.springframework.context.annotation.Bean; @SpringBootApplication@EnableEurekaClient@EnableFeignClients //开启feign@EnableCircuitBreaker //开启hystrix@EnableHystrixDashboard@EnableHystrix // spring cloud 2.x hystrix没有/actuator/hystrix.stream路径解决public class ConsumerHystrixApplication { public static void main(String[] args) { SpringApplication.run(ConsumerHystrixApplication.class, args); } // spring cloud 2.x hystrix没有/actuator/hystrix.stream路径解决 @Bean public ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/actuator/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; }}
1.2.8 测试
执行顺序:
先启动服务端 6001 eureka-server
在启动提供者1 8081 provider-user
最后启动消费者 8094 consumer-hystrix
访问Eureka控制台: http://localhost:6001/
访问请求: http://localhost:8094/hello/hi
注意:可能访问太快时第一次就出现断路器实现,这时访问太快,服务还未生效,多刷新几次,业务正常时应该出现上面的提示。
1.2.9 测试断路器
关闭provider-user,模拟服务失败宕机场景。
访问请求: http://localhost:8094/hello/hi
可以看到已经走了fallback方法。
重启provider-user服务,模拟服务修复,可以看到立即返回正确结果,说明服务正常时不会走断路器方法。
设置断点,和我们预想的相同,会发现只有异常时才走断路器的回调方法。
1.3 拓展:HystrixDashBoard
1.3.1 需要依赖jar包支持
只针对当前实例,actuator是SpringBoot提供的一些监控的扩展支持
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
1.3.2 pom.xml
<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> <version>LATEST</version></dependency>
1.3.3 HystrixRunApp.java
@EnableHystrixDashboard@EnableHystrix // spring cloud 2.x hystrix没有/actuator/hystrix.stream路径解决
// spring cloud 2.x hystrix没有/actuator/hystrix.stream路径解决@Beanpublic ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/actuator/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean;}
1.3.4 查看监控日志
访问链接:http://localhost:8094/hystrix
居然是404,为什么呢,spring-cloud 1.x 是OK的,但2.x不能访问
# 放开 hystrix 、health、info 等功能management.endpoints.web.exposure.include="*"
@EnableCircuitBreaker //开启hystrix@EnableHystrixDashboard@EnableHystrix // spring cloud 2.x hystrix没有/actuator/hystrix.stream路径解决
// spring cloud 2.x hystrix没有/actuator/hystrix.stream路径解决@Beanpublic ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/actuator/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean;}
访问8094,消费者链接,展示ping:一直打印,转个不停。
访问一次业务 http://localhost:8094/hello/hi
停止提供者,刷新消费者,开始打印日志信息
可以基于控制台访问(http://localhost:8094/hystrix)
输入链接:http://localhost:8094/actuator/hystrix.stream,点击monitor按钮
具体指标的含义为:
在监控的界面有两个重要的图形信息:一个实心圆和一条曲线。
l 实心圆:
1、通过颜色的变化代表了实例的健康程度,健康程度从绿色、黄色、橙色、红色递减。
2、通过大小表示请求流量发生变化,流量越大该实心圆就越大。所以可以在大量的实例中快速发现故障实例和高压实例。
l 曲线:用来记录2分钟内流浪的相对变化,可以通过它来观察流量的上升和下降趋势。
提供demo下载
spring-cloud-hystrix.zip
转载于:https://www.cnblogs.com/wood-life/p/10340602.html
Hystrix断路器(五)相关推荐
- 五、Hystrix断路器
Hystrix断路器 概述 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每一个依赖关系在某些时候将不可避免的失败. 服务雪崩 多个微服务之间调用的时候,假如微服务A调用微服务 ...
- Spring Cloud构建微服务架构:服务容错保护(Hystrix断路器)【Dalston版】
前言 在前两篇<Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)>和<Spring Cloud构建微服务架构:服务容错保护(Hystrix依赖隔离)&g ...
- Hystrix面试 - 深入 Hystrix 断路器执行原理
Hystrix面试 - 深入 Hystrix 断路器执行原理 RequestVolumeThreshold HystrixCommandProperties.Setter().withCircuitB ...
- SpringCloud中 Feign结合Hystrix断路器开发。
Feign结合Hystrix断路器开发: 转载于:https://www.cnblogs.com/longdb/p/10468371.html
- Hystrix断路器执行原理
深入 Hystrix 断路器执行原理 Hystrix熔断机制,用于监控微服务调用情况,当失败的情况达到预定的阈值(5秒失败20次),会打开断路器,拒绝所有请求,直到服务恢复正常为止. circuitB ...
- Hystrix断路器原理及实现(服务降级、熔断、限流)
Hystrix断路器原理及实现(服务降级.熔断.限流) 分布式系统面临的问题 Hystrix重要概念(面试常考) Hystrix案例 Hystrix 服务提供者 Hystrix 服务消费者 原因与解决 ...
- Netflix Hystrix断路器简介与工作原理
一.前言? 1.Netflix Hystrix断路器是什么? Netflix Hystrix是SOA/微服务架构中提供服务隔离.熔断.降级机制的工具/框架.Netflix Hystrix是断路器的一种 ...
- 微服务——Hystrix断路器(豪猪哥)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 概述 分布式系统面临的问题 是什么 能干嘛 Hystrix重要概念 服务降级(fallback) 哪些情况会触发降级 服务熔 ...
- SpringCloud07 - Hystrix 断路器
扯淡: 服务与服务之间有业务关联就需要调用,当被调用的服务发生故障(上线后多半是由于网路原因导致连接超时),必然会波及到服务调用者.通俗讲,断路器就是在低层级的服务发生故障时将服务间的连接断开. 个人 ...
- SpringClound——Hystrix断路器
SpringCloud学习资料汇总超级棒的 如上是我在看文章时忽然看到的一个很好的学习SpringCloud的网站 SpringClound--微服务概述--史上最烂 SpringClound--Sp ...
最新文章
- 前端JS的一些使用方法-持续更新
- 【CyberSecurityLearning 32】Apache配置、Apache的访问控制设定、LAMP平台的搭建
- 前端学习(1315):路由
- mybatis 打印SQL
- 【HDOJ】【3853】LOOPS
- 正则表达式判断ip格式
- ps -ef|grep htpd|wd -l
- git 提交代码的好习惯
- 计算机处理技术职业道德与论文,关于计算机职业道德的论文选题 计算机职业道德毕业论文题目怎样定...
- Hexo 搭建个人博客学习笔记(4):个性化主题Next个性化配置
- APP崩溃的主要原因
- 借助智能手机应用程序和可穿戴设备在夏季塑造身材
- 游戏引擎 白鹭(egret)学习总结(一)
- 英语音标,元音汇总(0基础学英语!必备!)
- 互联网卷王花落谁家?
- firefox windows旧版本下载
- PySide2 connect 时指定槽函数的参数
- springboot毕业设计 基于springboot在线视频点播系统毕业设计设计与实现参考
- unity编辑器拓展十一——将两张RGB图合并成一张
- 京挑客好推广步骤注意事项