Spring Cloud 入门 之 Hystrix 篇(四)
原文地址:Spring Cloud 入门 之 Hystrix 篇(四)
博客地址:http://www.extlight.com
一、前言
在微服务应用中,服务存在一定的依赖关系,如果某个目标服务调用慢或者有大量超时造成服务不可用,间接导致其他的依赖服务不可用,最严重的可能会阻塞整条依赖链,最终导致业务系统崩溃(又称雪崩效应)。
上述的问题将是本篇需要解决的问题。
二、简单介绍
2.1 请求熔断
断路器是一种开关设置,当某个服务单元发生故障之后,通过断路器的故障监控,向调用方返回一个符合预期的服务降级处理(fallback),而不是长时间的等待或者抛出调用方无法处理的异常,这样保证了服务调用方的线程不会长时间被占用,从而避免了故障在分布式系统的蔓延乃至崩溃。
2.2 服务降级
fallback 相当于是降级操作。对于查询操作, 我们可以实现一个 fallback 方法, 当请求后端服务出现异常的时候, 可以使用 fallback 方法返回的值。 fallback 方法的返回值一般是设置的默认值或者来自缓存,告知后面的请求服务不可用了,不要再请求了。
2.3 请求熔断和服务降级区别
相同:
目标一致:为了防止系统崩溃而实施的一种防御手段
表现形式一致:当请求目标在一定时间内无响应时,返回或执行默认响应内容
不同:
触发条件不同:下游服务出现故障触发请求熔断。系统负荷超过阈值触发服务降级。
管理目标层次不同:请求熔断针对所有微服务。服务降级针对整个系统中的外围服务。
2.4 实现方案
Spring Cloud Hystrix 实现了断路器、线程隔离等一系列服务保护功能。它是基于 Netflix 的开源框架 Hystrix 实现的,该框架的目的在于通过控制访问远程系统、服务和第三方库节点,从而对延迟和故障提供更强大的容错能力。
Hystrix 具备服务熔断、服务降级、线程和信号隔离、请求缓存、请求合并以及服务监控的能力。
三、请求熔断实战
本次测试案例基于之前发表的文章中介绍的案例进行演示,不清楚的读者请先转移至 《Spring Cloud 入门 之 Feign 篇(三)》 进行浏览。
现在的项目列表如下:
| 服务实例 | 端口 | 描述 |
|---|---|---|
| common-api | - | 公用的 api,如:实体类 |
| eureka-server | 9000 | 注册中心(Eureka 服务端) |
| goods-server | 8081 | 商品服务(Eureka 客户端) |
| goods-server-02 | 8082 | 商品服务(Eureka 客户端) |
| goods-server-03 | 8083 | 商品服务(Eureka 客户端) |
| order-server | 8100 | 订单服务(Eureka 客户端) |
在 order-server 项目中:
3.1 添加依赖
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
3.2 设置熔断策略
我们来修改获取下订单的方法,在 placeOrder 方法上加 @HystrixCommand 注解:
@Service
public class OrderServiceImpl implements OrderService{
@Autowired
private RestTemplate restTemplate;
// @Autowired
// private GoodsServiceClient goodsServiceClient;
@HystrixCommand(fallbackMethod = "defaultByPlaceOrder")
@Override
public void placeOrder(Order order) throws Exception{
Result result = this.restTemplate.getForObject("http://GOODS/goods/goodsInfo/" + order.getGoodsId(), Result.class);
// Result result = this.goodsServiceClient.goodsInfo(order.getGoodsId());
if (result != null && result.getCode() == 200) {
System.out.println("=====下订单====");
System.out.println(result.getData());
} else {
System.out.println(result.getMsg());
}
}
public void defaultByPlaceOrder(Order order) {
System.out.println("商品服务系统异常");
}
}
当调用商品服务超时或出现异常时,Hystrix 会调用 @HystrixCommand 中指定的 fallbackMethod 方法获取返回值或执行异常处理。
注意:fallbackMethod 方法要求与正常方法有相同的入参和回参。
3.3 启动熔断功能
在启动类上添加 @EnableCircuitBreaker 注解:
@EnableCircuitBreaker
@EnableEurekaClient
@SpringBootApplication
public class OrderServerApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServerApplication.class, args);
}
}
3.4 熔断测试
- 我们首先演示没有开启熔断的功能,即先把上边的 @EnableCircuitBreaker 注解进行注释。
启动好所有项目,使用 Postman 请求 order-server 进行下单操作,运行结果如下:

当我们请求发送的 goodsId 的商品不存在,服务提供方抛会异常,调用方无法处理,因此只能展示图中的异常信息。
- 下面,我们再将 @EnableCircuitBreaker 注解的注释放开,运行结果如下:

从图中可知,虽然请求了一个 goodsId 不存在的商品,但是调用方(order-server)开启了熔断机制,执行默认方法,从而使接口能正常通信而不是抛出调用方不可处理的异常导致整个系统不能正常运行。
看到这里,或许会有读者产生一个疑问,如果类中定义 N 个方法,是不是意味着同时也要定义 N 个异常处理的方法呢,答案是否定的。
Hystrix 还提供了 @DefaultProperties 统一处理请求熔断,在该注解上设置 defaultFallback 属性值,即熔断开启后要执行的方法。
@Service
@DefaultProperties(defaultFallback = "defaultByHystrix")
public class OrderServiceImpl implements OrderService{
// @Autowired
// private RestTemplate restTemplate;
@Autowired
private GoodsServiceClient goodsServiceClient;
@HystrixCommand
@Override
public void placeOrder(Order order) throws Exception{
// Result result = this.restTemplate.getForObject("http://GOODS/goods/goodsInfo/" + order.getGoodsId(), Result.class);
Result result = this.goodsServiceClient.goodsInfo(order.getGoodsId());
if (result != null && result.getCode() == 200) {
System.out.println("=====下订单====");
System.out.println(result.getData());
} else {
System.out.println(result.getMsg());
}
}
public void defaultByHystrix() {
System.out.println("商品服务系统异常");
}
}
注意:defaultFallback 定义的方法必须是无参的。
四、服务降级实战
在 common-api 项目中:
4.1 定义 Fallback
@Component
public class GoodsServiceClientFallbackFactory implements FallbackFactory<GoodsServiceClient> {
@Override
public GoodsServiceClient create(Throwable cause) {
return new GoodsServiceClient() {
@Override
public Result goodsInfo(String goodsId) {
return Result.fail(500, "商品服务系统出现异常,请联系管理员");
}
};
}
}
使用单独的类处理异常逻辑,当与服务端无法正常通信时调用此类中的方法返回结果。
4.2 修改 Feign 客户端
将上边定义好的 FallbackFactory 设置到 @FeignClient 注解上:
@FeignClient(value="GOODS", fallbackFactory = GoodsServiceClientFallbackFactory.class)
public interface GoodsServiceClient {
@RequestMapping("/goods/goodsInfo/{goodsId}")
public Result goodsInfo(@PathVariable("goodsId") String goodsId);
}
4.3 开启服务降级功能
在 order-server 项目中:
server:
port: 8100
spring:
application:
name: ORDER
eureka:
instance:
instance-id: order-api-8100
prefer-ip-address: true # 访问路径可以显示 IP
client:
service-url:
defaultZone: http://localhost:9000/eureka/ # 注册中心访问地址
feign:
hystrix:
enabled: true
4.4 去掉 @HystrixCommand 配置
@Service
//@DefaultProperties(defaultFallback = "defaultByHystrix")
public class OrderServiceImpl implements OrderService{
// @Autowired
// private RestTemplate restTemplate;
@Autowired
private GoodsServiceClient goodsServiceClient;
// @HystrixCommand
@Override
public void placeOrder(Order order) throws Exception{
// Result result = this.restTemplate.getForObject("http://GOODS/goods/goodsInfo/" + order.getGoodsId(), Result.class);
Result result = this.goodsServiceClient.goodsInfo(order.getGoodsId());
if (result != null && result.getCode() == 200) {
System.out.println("=====下订单====");
System.out.println(result.getData());
} else {
System.out.println(result.getMsg());
}
}
// public void defaultByHystrix() {
// System.out.println("商品服务系统异常");
// }
}
4.5 测试服务降级
在启动类上加 FallbackFactory 类的包扫描目录:
@ComponentScan(basePackages = {"com.extlight.springcloud"}) // 为了能扫描 common-api 项目中的 GoodsServiceClientFallbackFactory
@EnableFeignClients(basePackages = {"com.extlight.springcloud"})
@EnableEurekaClient
@SpringBootApplication
public class OrderServerApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServerApplication.class, args);
}
}
打开 Postman 请求下单接口,结果如下图:

我们手动关闭 2 个商品服务,保留一个商品服务并多次请求商品服务接口,从而出模拟商品服务超过预定荷载情景,最终看到图中服务降级功能。当有请求再次访问商品服务时默认返回 GoodsServiceClientFallbackFactory 中定义的内容。
五、仪表盘
除了服务熔断、降级的功能外,Hystrix 还提供了准及时的调用监控。 Hystrix 会持续地记录所有通过 Hystrix 发起的请求的执行信息,并以统计报表和图形方式展示给用户。
5.1 配置被监控方
order-server 项目中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
修改 application.yml,开放端口:
management:
endpoints:
web:
exposure:
include: "*"
5.2 配置监控方
1.新建一个名为 hystrix-dashboard 项目,添加如下依赖:
<!-- hystrix-dashboard -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
2.新建 application.yml
server:
port: 9300
spring:
application:
name: Hystrix-Dashboard
3.开启监控功能
在启动类上添加 @EnableHystrixDashboard 注解。
@EnableHystrixDashboard
@SpringBootApplication
public class HystrixdashboardApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixdashboardApplication.class, args);
}
}
启动,浏览器访问: http://localhost:9300/hystrix:

5.3 监控设置
我们以监控 order-server 为例,在监控界面添加监控信息:
# 需要监控的服务地址
http://localhost:8100/actuator/hystrix.stream
delay: 请求间隔时间
title: 监控名称
点击 monitor stream
批量访问 order-server 服务的下单接口。
最终效果如下:

通过批量访问下单接口,发现图中实心圆和曲线发生了变化。那我们如何根据这两个图形查看监控信息呢?
实心圆:通过颜色的变化代表实例的健康程度,健康度从绿色>黄色>橙色>红色递减。其大小也会根据实例的请求流量发生变化,流量越大实心圆越大。
曲线:用来记录间隔时间内流量的相对变化,通常可以观察到流量的上升和下降趋势。
六、案例源码
七、参考资料
Spring Cloud 入门 之 Hystrix 篇(四)的更多相关文章
- Spring Cloud 入门 之 Zuul 篇(五)
原文地址:Spring Cloud 入门 之 Zuul 篇(五) 博客地址:http://www.extlight.com 一.前言 随着业务的扩展,微服务会不对增加,相应的其对外开放的 API 接口 ...
- Spring Cloud 入门 之 Config 篇(六)
原文地址:Spring Cloud 入门 之 Config 篇(六) 博客地址:http://www.extlight.com 一.前言 随着业务的扩展,为了方便开发和维护项目,我们通常会将大项目拆分 ...
- Spring Cloud 入门 之 Feign 篇(三)
原文地址:Spring Cloud 入门 之 Feign 篇(三) 博客地址:http://www.extlight.com 一.前言 在上一篇文章<Spring Cloud 入门 之 Ribb ...
- Spring Cloud 入门 之 Ribbon 篇(二)
原文地址:Spring Cloud 入门 之 Ribbon 篇(二) 博客地址:http://www.extlight.com 一.前言 上一篇<Spring Cloud 入门 之 Eureka ...
- Spring Cloud 入门 之 Eureka 篇(一)
原文地址:Spring Cloud 入门 之 Eureka 篇(一) 博客地址:http://www.extlight.com 一.前言 Spring Cloud 是一系列框架的有序集合.它利用 Sp ...
- Spring Cloud入门教程-Hystrix断路器实现容错和降级
简介 Spring cloud提供了Hystrix容错库用以在服务不可用时,对配置了断路器的方法实行降级策略,临时调用备用方法.这篇文章将创建一个产品微服务,注册到eureka服务注册中心,然后我们使 ...
- <Spring Cloud>入门五 hystrix
1.服务熔断 1.1引入坐标 <dependency> <groupId>org.springframework.cloud</groupId> <artif ...
- spring cloud 入门系列四:使用Hystrix 实现断路器进行服务容错保护
在微服务中,我们将系统拆分为很多个服务单元,各单元之间通过服务注册和订阅消费的方式进行相互依赖.但是如果有一些服务出现问题了会怎么样? 比如说有三个服务(ABC),A调用B,B调用C.由于网络延迟或C ...
- Spring Cloud 入门教程(八): 断路器指标数据监控Hystrix Dashboard 和 Turbine
1. Hystrix Dashboard (断路器:hystrix 仪表盘) Hystrix一个很重要的功能是,可以通过HystrixCommand收集相关数据指标. Hystrix Dashboa ...
随机推荐
- Microsoft 数据访问组件 (MDAC) 的版本历史记录
http://support.microsoft.com/kb/231943/zh-cn http://support.microsoft.com/kb/301202
- docker(一)安装和必要的配置。
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...
- java学习笔记 --- 集合(续)
1.map集合 1.1.特点:将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值. 1.2.Map集合和Collection集合的区别? Map集合存储元素是成对出现的,Map集 ...
- L241
Parents, try to get enough sleep to role model good habits to children. Bessesen notes that some med ...
- 关于DIY操作系统的断更道歉
去年9月份正是开学的时候,刚开学没感觉忙.但是随着课程的深入,而且都是专业课,再加上招娉会一个接一个的来,渐渐显得力不从心.由于我对操作系统这一方面也是一知半解,以前也没有系统地学过计算机方面的东西, ...
- PostgreSQL数据库创建只读用户总结
好久没有弄,有点忘了,今天有客户问这个问题,发现几个SQL还解决不了,于是总结一下: --以超级用户登录数据库,创建用户: postgres=# create user test_read_only ...
- 12个有趣的 XSS Vector
XSS Vector #1 <script src=/〱20.rs></script> URL中第二个斜杠在Internet Explorer下(测试于IE11)可被U+303 ...
- WTForms组件
WTForms组件 WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证. 注意: from wtforms import Form 和 from flask_wtf ...
- vs2010将写好的软件打包安装包经验
(1) 用VS2010打开已经编写好准备做安装包的软件程序,右击解决方案,添加新建项目. (2) 在“新建项目”对话框中,选择“其他项目类型”,再选择“安装和部署”,然后在模板中选择“安装项目” (3 ...
- Appium 并发多进程基于 Pytest框架
前言: 之前通过重写unittest的初始化方法加入设备参数进行并发,实现了基于unittest的appium多设备并发,但是考虑到unittest的框架实在过于简陋,也不方便后期的Jenkins的持 ...