目录

一、 Hystrix 简介

1 什么是灾难性雪崩效应

2 什么是 Hystrix

二、 服务降级

1 修改 application service 代码

2 application client POM 依赖

3 application client 容错处理代码

4 application client 配置文件 application.yml

5 application client 启动类

三、 服务熔断

1 application client POM 依赖

2 application client 容错处理代码

3 application client 配置文件 application.yml

4 application client 启动类

四、 请求缓存

1 修改 application service 代码

2 application client POM 依赖

3 application client 容错处理代码

4 application client 配置文件 application.yml

5 application client 启动类

五、 Openfeign 的雪崩处理

1 服务降级

1.1 POM 依赖

1.2 application client 接口

1.3 application client 接口实现

1.4 application client 配置文件 application.yml

1.5 applicaiton client 启动类

2 服务熔断

六、 可视化的数据监控 Hystrix-dashboard

1 POM 依赖

2 配置文件 application.yml

3 启动类

4 访问 Hystrix 监控数据


一、 Hystrix 简介

1 什么是灾难性雪崩效应

造成灾难性雪崩效应的原因,可以简单归结为下述三种:
服务提供者不可用。如:硬件故障、程序 BUG、缓存击穿、并发请求量过大等。
重试加大流量。如:用户重试、代码重试逻辑等。
服务调用者不可用。如:同步请求阻塞造成的资源耗尽等。
雪崩效应最终的结果就是:服务链条中的某一个服务不可用,导致一系列的服务不可
用,最终造成服务逻辑崩溃。这种问题造成的后果,往往是无法预料的。
解决灾难性雪崩效应的方式通常有:降级、熔断和请求缓存。

2 什么是 Hystrix

Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力。
本文所说的 Hystrix 是 Netflix 开源的一款容错框架,同样具有自我保护能力。为了实现容
错和自我保护,下面我们看看 Hystrix 如何设计和实现的。
Hystrix 设计目标:
1、 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的
2、 阻止故障的连锁反应
3、 快速失败并迅速恢复
4、 回退并优雅降级
5、 提供近实时的监控与告警
Hystrix 遵循的设计原则:
1、 防止任何单独的依赖耗尽资源(线程)
2、 过载立即切断并快速失败,防止排队
3、 尽可能提供回退以保护用户免受故障
4、 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响
5、 通过近实时的指标,监控和告警,确保故障被及时发现
6、 通过动态修改配置属性,确保故障及时恢复
7、 防止整个依赖客户端执行失败,而不仅仅是网络通信
Hystrix 如何实现这些设计目标?
1、 使用命令模式将所有对外部服务(或依赖关系)的调用包装在 HystrixCommand
或 HystrixObservableCommand 对象中,并将该对象放在单独的线程中执行;
2、 每个依赖都维护着一个线程池(或信号量),线程池被耗尽则拒绝请求(而不是
让请求排队)。
3、 记录请求成功,失败,超时和线程拒绝。
4、 服务错误百分比超过了阈值,熔断器开关自动打开,一段时间内停止对该服务的
所有请求。
5、 请求失败,被拒绝,超时或熔断时执行降级逻辑。
6、 近实时地监控指标和配置的修改。
在 Spring cloud 中处理服务雪崩效应,都需要依赖 hystrix 组件。在 Application Client
应用的 pom 文件中都需要引入下述依赖:

二、 服务降级

降级是指,当请求超时、资源不足等情况发生时进行服务降级处理,不调用真实服务
逻辑,而是使用快速失败(fallback)方式直接返回一个托底数据,保证服务链条的完整,
避免服务雪崩。
解决服务雪崩效应,都是避免 application client 请求 application service 时,出现服务
调用错误或网络问题。处理手法都是在 application client 中实现。我们需要在 application
client 相 关 工 程 中 导 入 hystrix 依 赖 信 息 。 并 在 对 应 的 启 动 类 上 增 加 新 的 注 解
@EnableCircuitBreaker,这个注解是用于开启 hystrix 熔断器的,简言之,就是让代码中的
hystrix 相关注解生效。
具体实现过程如下:

1 修改 application service 代码

修改 application service 工程中的代码,模拟超时错误。此模拟中,让服务端代码返回
之前休眠 2000 毫秒,替代具体的复杂服务逻辑。
@RestController
public class ServiceController {
@GetMapping
public Object first(){
try {
// 用于模拟远程服务调用延时。
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "测试 Spring Cloud Netflix Ribbon 开发服务提供者";
}
}

2 application client POM 依赖

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

3 application client 容错处理代码

@Service
public class ClientServiceImpl implements ClientService {
@Autowired
private LoadBalancerClient
loadBalancerClient;
/**
* @HystrixCommand - 开启 Hystrix 容错处理的注解。代表当前方法如果出现服务
调用问题,使用 Hystrix 容错处理逻辑来处理*
属性 fallbackMethod - 如果当前方法调用服务,远程服务出现问题的时候,调
用本地的哪个方法得到托底数据。
*/
@HystrixCommand(fallbackMethod = "downgradeFallback")
@Override
public String first() {
ServiceInstance si = this.loadBalancerClient.choose("application-service");
StringBuilder sb = new StringBuilder();
sb.append("http://").append(si.getHost())
.append(":").append(si.getPort()).append("/");
System.out.println("本次访问的 service 是: " + sb.toString());
RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<String> type = new ParameterizedTypeReference<String>(){};
ResponseEntity<String> response =
rt.exchange(sb.toString(), HttpMethod.GET, null, type);
String
result = response.getBody();
return
result;
}
// 本地容错方法,只有远程服务调用过程出现问题的时候,才会调用此方法,获取
托底数据。保证服务完整性。
private String downgradeFallback(){
return "服务降级方法返回托底数据";
}
}

4 application client 配置文件 application.yml

5 application client 启动类

三、 服务熔断

当一定时间内,异常请求比例(请求超时、网络故障、服务异常等)达到阀值时,启动熔断器,熔断器一旦启动,则会停止调用具体服务逻辑,通过 fallback 快速返回托底数
据,保证服务链的完整。
熔断有自动恢复机制,如:当熔断器启动后,每隔 5 秒,尝试将新的请求发送给服务
提供者,如果服务可正常执行并返回结果,则关闭熔断器,服务恢复。如果仍旧调用失败,
则继续返回托底数据,熔断器持续开启状态。
具体实现过程如下:

1 application client POM 依赖

2 application client 容错处理代码

@Service
public class ClientServiceImpl
implements ClientService {
@Autowired
private LoadBalancerClient
loadBalancerClient;
/**
* @HystrixCommand - 开启 Hystrix 容错处理的注解。代表当前方法如果出现服务
调用问题,使用 Hystrix 容错处理逻辑来处理
*
属性 fallbackMethod - 如果当前方法调用服务,远程服务出现问题的时候,调
用本地的哪个方法得到托底数据。
*/
@HystrixCommand(fallbackMethod = "downgradeFallback",
commandProperties = {
// 默认 20 个;10s 内请求数大于 20 个时就启动熔断器,当请求符合熔断条件时将触发 fallback 逻辑
@HystrixProperty(name =
HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "10"),
// 请求错误率大于 50%时就熔断,然后 for 循环发起请求,当请求符合熔断
条件时将触发
@HystrixProperty(name =
HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "50"),
// 默认 5 秒;熔断多少秒后去尝试请求
@HystrixProperty(name =
HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value =
"5000")
}
)
@Override
public String first() {
ServiceInstance si =
this.loadBalancerClient.choose("application-service");
StringBuilder sb = new StringBuilder();
sb.append("http://").append(si.getHost())
.append(":").append(si.getPort()).append("/");
System.out.println("本次访问的 service 是: " + sb.toString());
RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<String> type =
new ParameterizedTypeReference<String>() {
};
ResponseEntity<String> response =
rt.exchange(sb.toString(), HttpMethod.GET, null, type);
String
result = response.getBody();
return
result;
}
// 本地容错方法,只有远程服务调用过程出现问题的时候,才会调用此方法,获取
托底数据。保证服务完整性。
private String downgradeFallback(){
return "服务降级方法返回托底数据";
}

3 application client 配置文件 application.yml

4 application client 启动类

四、 请求缓存

请求缓存:通常意义上说,就是将同样的 GET 请求结果缓存起来,使用缓存机制(如
redis、mongodb)提升请求响应效率。
使用请求缓存时,需要注意非幂等性操作对缓存数据的影响。
请求缓存是依托某一缓存服务来实现的。在案例中使用 redis 作为缓存服务器,那么
可以使用 spring-data-redis 来实现 redis 的访问操作。

1 修改 application service 代码

@RestController
public class ServiceController {
@PostMapping("/testPost")
public Object testPost(){
System.out.println("testPost method run");
return "写操作返回";
}
@GetMapping("/testGet")
public Object testGet(){
System.out.println("testGet method run");
return "读操作返回";
}
@GetMapping
public Object first(){
System.out.println("run");
try {
// 用于模拟远程服务调用延时。Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "测试 Spring Cloud Netflix Ribbon 开发服务提供者";
}
}

2 application client POM 依赖

3 application client 容错处理代码

/**
*
在类上,增加@CacheConfig 注解,用来描述当前类型可能使用 cache 缓存。
*
如果使用缓存,则缓存数据的 key 的前缀是 cacheNames。
*
cacheNames 是用来定义一个缓存集的前缀命名的,相当于分组。
*/
@CacheConfig(cacheNames = "test.hystrix.caches")
@Service
public class ClientServiceImpl implements ClientService {
@Autowired
private LoadBalancerClient loadBalancerClient;
/**
* @HystrixCommand - 开启 Hystrix 容错处理的注解。代表当前方法如果出现服
务调用问题,使用 Hystrix 容错处理逻辑来处理
*
属性 fallbackMethod - 如果当前方法调用服务,远程服务出现问题的时候,
调用本地的哪个方法得到托底数据。
*/
@HystrixCommand(fallbackMethod = "downgradeFallback",
commandProperties = {
// 默认 20 个;10s 内请求数大于 20 个时就启动熔断器,当请求符合熔断
条件时将触发 fallback 逻辑@HystrixProperty(name =
HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "10"),
// 请求错误率大于 50%时就熔断,然后 for 循环发起请求,当请求符合熔
断条件时将触发
@HystrixProperty(name =
HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "50"),
// 默认 5 秒;熔断多少秒后去尝试请求
@HystrixProperty(name =
HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,
value = "5000")
}
)
@Override
public String first() {
ServiceInstance si = this.loadBalancerClient.choose("application-service");
StringBuilder sb = new StringBuilder();
sb.append("http://").append(si.getHost())
.append(":").append(si.getPort()).append("/");
System.out.println("本次访问的 service 是: " + sb.toString());
RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<String> type =
new ParameterizedTypeReference<String>() {};
ResponseEntity<String> response =
rt.exchange(sb.toString(), HttpMethod.GET, null, type);
String
result = response.getBody();
return result;
}
/**
*
@Cacheable - 将当期方法的返回值缓存到 cache 中。
*
只要方法增加了@Cacheable 注解,每次调用当前方法的时候,spring cloud
都会先访问 cache 获取数据,
*
如果 cache 中没有数据,则访问远程服务获取数据。远程服务返回数据,先保
存在 cache 中,再返回给客户端。
*
如果 cache 中有数据,则直接返回 cache 中的数据,不会访问远程服务。*
请求缓存会有缓存数据不一致的可能。缓存数据过期、失效、脏数据等情况。
*
一旦使用了请求缓存来处理幂等性请求操作。则在非幂等性请求操作中必须管
理缓存。避免缓存数据的错误。
* @return
*/
@Override
@Cacheable("myCache")
public String testGet() {
ServiceInstance si = this.loadBalancerClient.choose("application-service");
StringBuilder sb = new StringBuilder();
sb.append("http://").append(si.getHost())
.append(":").append(si.getPort()).append("/testGet");
System.out.println("本次访问的 service 是: " + sb.toString());
RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<String> type =
new ParameterizedTypeReference<String>() { };
ResponseEntity<String> response =
rt.exchange(sb.toString(), HttpMethod.GET, null, type);
String result = response.getBody();
return
result;
}
/**
*
@CacheEvict - 管理缓存。根据参数 key 删除缓存中对应的缓存数据。
*
@return
*/
@Override
@CacheEvict("myCache")
public String testPost() {
ServiceInstance si = this.loadBalancerClient.choose("application-service");
StringBuilder sb = new StringBuilder();
sb.append("http://").append(si.getHost())
.append(":").append(si.getPort()).append("/testPost");
System.out.println("本次访问的 service 是: " + sb.toString());RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<String> type =
new ParameterizedTypeReference<String>() {
};
ResponseEntity<String> response =
rt.exchange(sb.toString(), HttpMethod.POST, null, type);
String result = response.getBody();
return result;
}
// 本地容错方法,只有远程服务调用过程出现问题的时候,才会调用此方法,获
取托底数据。保证服务完整性。
private String downgradeFallback(){
return "服务降级方法返回托底数据";
}
}

4 application client 配置文件 application.yml

5 application client 启动类

五、 Openfeign 的雪崩处理

在声明式远程服务调用 Openfeign 中,实现服务灾难性雪崩效应处理也是通过 Hystrix
实现的。而 feign 启动器 spring-cloud-starter-openfeign 中是包含 Hystrix 相关依赖的。如果
只使用服务降级功能则不需要做独立依赖。如果需要使用 Hystrix 其他服务容错能力,需
要依赖 spring-cloud-starter-netflix-hystrix 资源。从 Dalston 版本后,feign 默认关闭 Hystrix
支持。所以必须在全局配置文件中开启 feign 技术中的 Hystrix 支持。具体实现如下:

1 服务降级

1.1 POM 依赖

Openfeign 的启动器依赖 spring-cloud-starter-openfeign 中,自带 Hystrix 处理相关依赖,
所以不需要修改 POM 依赖,直接通过配置即可开启容错处理机制。

1.2 application client 接口

/**
* 注解属性 fallback - 当前接口远程调用服务发生问题时,使用哪一个对象中的对应方
法用于实现容错逻辑。
*
Openfeign 技术中,容错处理是使用当前接口的实现类实现的。
*
实现类中的方法实现,就是对应的容错 fallback 处理逻辑。
*/
@FeignClient(name="openfeign-service", fallback =
FirstClientServiceImpl.class)
public interface FirstClientService extends FirstServiceAPI {
}

1.3 application client 接口实现

/**
*
当前类型的实例必须由 Spring 容器管理,需要使用@Component 注解描述。
*
每个实现方法对应远程服务调用的容错处理逻辑。
*/@Component
public class FirstClientServiceImpl implements FirstClientService {
@Override
public List<String> testFeign()
{
return Arrays.asList("Openfeign 返回托底数据");
}
@Override
public User getMultiParams(Integer id, String name) {
User user = new User();
user.setId(0);
user.setUsername("托底数据");
user.setRemark("getMultiParams");
return user;
}
@Override
public User postMultiParams(Integer id, String name) {
User user = new User();
user.setId(0);
user.setUsername("托底数据");
user.setRemark("postMultiParams");
return user;
}
@Override
public User postObjectParam(User pojo) {
User user = new User();
user.setId(0);
user.setUsername("托底数据");
user.setRemark("postObjectParam");
return user;
}
}

1.4 application client 配置文件 application.yml

1.5 applicaiton client 启动类

2 服务熔断

在 Openfeign 技术中,服务熔断对代码和依赖没有其他任何要求,只需要增加对应的
配置即可,具体配置如下:

六、 可视化的数据监控 Hystrix-dashboard

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

1 POM 依赖

Hystrix Dashboard 是针对 Hystrix 容错处理相关数据的监控工具。只要在使用了 Hystrix
技术的应用工程中导入对应依赖即可。注意:如果在 Openfeign 技术中开启 Hystrix
Dashboard 监控,则需要将 spring-cloud-starter-netflix-hystrix 启动器导入 POM 文件,否则
无法在启动类上使用@EnableCircuitBreaker 注解。

2 配置文件 application.yml

3 启动类

4 访问 Hystrix 监控数据

通过浏览器访问提供监控访问路径的应用,具体地址为:
http://ip:port/actuator/hystrix.stream
得到的监控结果如下
这种监控数据的获取都是 JSON 数据。且数据量级较大。不易于查看。可以使用 Hystrix
Dashboard 提供的视图界面来观察监控结果。视图界面访问路径为: http://ip:port/hystrix。

进入后的监控视图界面具体含义如下:

Spring Cloud Netflix Hystrix相关推荐

  1. Spring Cloud Netflix Hystrix介绍和使用

    前面我们搭建了具有服务降级功能的Hystrix客户端,现在我们来详细了解下Hystrix的一些功能. Hystrix的意思是豪猪,大家都知道,就是长满刺的猪...实际上,它表明了该框架的主要功能:自我 ...

  2. Spring Cloud Netflix五大组件简介

    微服务与微服务架构 微服务的优缺点 优点 缺点 Dubbo与Spring Cloud Spring Cloud Netflix Eureka Eureka的自我保护机制 Eureka和ZooKeepe ...

  3. Spring Cloud Netfix Hystrix(断路器)

    一.灾难性雪崩 造成灾难性雪崩效应的原因,可以简单归结为下述三种: 服务提供者(Application Service)不可用.如:硬件故障.程序BUG.缓存击穿.并发请求量过大等. 重试加大流量.如 ...

  4. Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失(续)

    前言 上篇文章<Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失>我们对ThreadLocal数据丢失进行了详细的分析,并通过代码的方式复现了这个问题. ...

  5. Spring Cloud Netflix项目进入维护模式之我见

    这两天看到一则新闻:https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now#spring-cloud-ne ...

  6. SpringCloud学习笔记(1)- Spring Cloud Netflix

    文章目录 SpringCloud学习笔记(1)- Spring Cloud Netflix 单体应用存在的问题 Spring Cloud Eureka Eureka Server代码实现 Eureka ...

  7. Spring Cloud Netflix之Eureka上篇

    前言:Spring Cloud NetFlix这个项目对NetFlix中一些久经考验靠谱的服务发现,熔断,网关,智能路由,以及负载均衡等做了封装,并通过注解的或简单配置的方式提供给Spring Clo ...

  8. Spring Cloud Netflix中文文档翻译笔记

    原文地址:http://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/1.2.2.RELEASE/ Spring Cloud Net ...

  9. Spring Cloud之Hystrix服务容错

    Spring Cloud之Hystrix服务容错 Hystrix的概述 Hystrix的使用 相关依赖 Eureka注册中心 服务提供者 服务消费者 执行测试 @HystrixCommand详解 服务 ...

最新文章

  1. linux pureftp mysql_在Ubuntu下安装apache2+php5+mysql5+pureftp+ftp
  2. 批量 kill mysql 中运行时间长的sql
  3. linux下用c 开发web,用C一步步开发web服务器(2)
  4. python3 遍历列表得到序号索引和值
  5. python从零基础到项目实战怎么样-Python 3.x网络爬虫从零基础到项目实战
  6. MySQL 5.7.11 重置root密码
  7. 3-5比较和Fancy Indexing
  8. 容器的基础 XmlBeanFactory(下篇)
  9. how to reference the parent form from the WPF control(Control in ElementHost)
  10. C++函数的返回值是指针
  11. OpenCASCADE Texture Mapping
  12. java答题小程序代码_分享一个java技术开发的微信答题小程序仿头脑王者源码
  13. QTabWidget 删除tab
  14. 阿里云服务器安全组授权对象ip设置
  15. 人工智能设计------------意识可控与意识不可控(三)
  16. 计算机被限制压缩包打不开怎么办,【解决】压缩文件打不开,压缩文件损坏怎么修复?...
  17. android 手机壁纸制作教程,教程:让你的手机桌面瞬间高逼格!
  18. 谈 Scratch 版“植物大战僵尸”
  19. 服务器操作系统的特点,服务器操作系统的特点
  20. uni-app对接支付

热门文章

  1. 抖音素材哪里收集_抖音短视频的内容素材从哪里来,抖音内容素材哪里收集
  2. 物联网还有哪些创业机会?
  3. 丹尼斯·里奇-C语言创始人
  4. jenkins 邮件配置展示change信息
  5. ## IDEA创建maven项目没有src目录问题解决
  6. 使用android.view.TouchDelegate扩大View的触摸点击区域
  7. 鸡声茅店月,人迹板桥霜;莫道君行早,更有早行人
  8. Java、JSP飞机航班信息查询系统
  9. 黄聪:清理微信浏览网站的缓存,Cookie
  10. 模块独立性的度量(耦合度和内聚度)