java框架之SpringCloud(5)-Hystrix服务熔断、降级与监控
前言
分布式系统面临的问题
复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。不做任何处理的情况下,很容易导致服务雪崩。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几分钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列、线程和其它系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以免因为单个依赖关系的失败对整个应用程序或系统造成影响。
断路器
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应,而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
服务熔断
介绍
服务熔断是应对服务雪崩的一种微服务链路保护机制。一般是某个服务故障或者异常引起,类似现实世界中的“保险丝”,当某个异常条件被触发,直接熔断整个服务,而不是一直等到此服务超时。
当扇出链路的某个微服务不可用或响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回“错误”地响应信息。 当检测到该节点微服务调用响应正常后恢复调用链路。在 SpringCloud 中的熔断机制是通过 Hystrix 实现。Hystrix 会监控微服务间的调用状况,当失败的调用到一定阈值,缺省是 5 秒内 20 次调用失败就会启动熔断机制。启用熔断机制的注解是 @HystrixCommand 。
Hystrix 是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多以来不可避免的会调用失败,比如超时、异常等,Hystrix 能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
使用
1、复制 "microservicecloud-provider-dept-8001" 子工程改名为 "microservicecloud-provider-dept-hystrix-8001",新增断路器依赖:
<!--Hystrix 断路器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2、修改微服务实例 Id:
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis 配置文件路径
type-aliases-package: zze.springcloud.entities # 所有 Entity 别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper 映射文件
spring:
application:
name: microservicecloud-provider-dept # 当前微服务名称
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql 驱动包
url: jdbc:mysql:///springcloud_8001 # 数据库连接 root
username: root
password: root
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
eureka:
client: # 将当前工程作为 Eureka 客户端
service-url:
# 单机版
# defaultZone: http://localhost:7001/eureka # Eureka 服务端地址
defaultZone: http://www.eurekaserver1.com:7001/eureka,http://www.eurekaserver2.com:7002/eureka,http://www.eurekaserver3.com:7003/eureka
instance:
instance-id: microservicecloud-provider-dept-hystrix-8001
prefer-ip-address: true # 访问路径显示 IP
info:
host: ${java.rmi.server.hostname}
port: ${server.port}
app.name: microservicecloud-provider-dept-8001
build.artifactId: ${project.artifactId}
build.version: ${project.version}
application.yml
3、修改 Controller,给 get 方法添加上熔断注解,指定回调方法:
package zze.springcloud.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import zze.springcloud.entities.Dept;
import zze.springcloud.service.DeptService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/dept")
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/add")
public boolean add(@RequestBody Dept dept) {
return deptService.add(dept);
}
@GetMapping("/get/{id}")
@HystrixCommand(fallbackMethod = "fallback_get") // fallbackMethod 指定回调方法名,get 方法异常时会调用指定的方法
public Dept get(@PathVariable Long id) {
Dept dept = deptService.get(id);
if(null == dept){
throw new RuntimeException("没有 id 为" + id + "的这个部门");
}
return dept;
}
/**
* get 方法熔断回调
*/
private Dept fallback_get(@PathVariable Long id){
return new Dept().setDeptNo(id).setDeptName("该部门不存在").setDbSource("数据源中没有这个部门");
}
@GetMapping("/list")
public List<Dept> list() {
return deptService.list();
}
}
zze.springcloud.controller.DeptController
4、修改主启动类,使用注解添加 Hystrix 服务熔断支持:
package zze.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker // Hystrix 熔断功能支持
public class Application_8001 {
public static void main(String[] args) {
SpringApplication.run(Application_8001.class, args);
}
}
zze.springcloud.Application_8001
5、测试:
1、启动 microservicecloud-provider-dept-hystrix-8001 服务 2、访问 http://localhost:8001/dept/get/1 时正常返回数据 3、访问 http://localhost:8001/dept/get/11 时执行了熔断方法,返回了自定义的数据信息:

test
服务端(被调用端)操作,服务熔断实际上类似于异常处理,让服务在发生不可预料的异常时可控的返回一个客户端可处理的结果。
服务降级
简介
什么是服务降级?当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
所谓降级,一般是从整体负荷考虑。就是当某个服务熔断之后,对应服务将不再被调用,此时客户端可以自己准备一个本地的回调,返回一个缺省值。这样做,虽然服务水平下降了,但好歹能用,比直接挂掉要强。
服务降级主要用于什么场景呢?当整个微服务架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,我们可以将一些不重要或不紧急的服务或任务进行服务的延迟使用或暂停使用。
使用
1、修改 "microservicecloud-provider-dept-8001" 的 Controller 模拟异常情况:
package zze.springcloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import zze.springcloud.entities.Dept;
import zze.springcloud.service.DeptService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/dept")
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/add")
public boolean add(@RequestBody Dept dept) {
return deptService.add(dept);
}
@GetMapping("/get/{id}")
public Dept get(@PathVariable Long id) {
Dept dept = deptService.get(id);
if(null == dept){
throw new RuntimeException("没有 id 为" + id + "的这个部门");
}
return dept;
}
@GetMapping("/list")
public List<Dept> list() {
return deptService.list();
}
@Autowired
private DiscoveryClient discoveryClient;
/**
* 获取所有注册到 EurekaServer 的服务信息
*
* @return
*/
@GetMapping("/discovery")
public Object discovery() {
Map<String, Object> map = new HashMap<>();
// 获取所有注册到 EurekaServer 的微服务名称,对应 spring.application.name
List<String> services = discoveryClient.getServices();
for (String service : services) {
// 获取对应服务所有实例
List<ServiceInstance> instances = discoveryClient.getInstances(service);
map.put(service, instances);
}
return map;
}
}
zze.springcloud.controller.DeptController
2、修改 "microservicecloud-consumer-dept-feign" 工程,新增断路器依赖,新增熔断回调工厂类:
package zze.springcloud.service.fallback;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import zze.springcloud.entities.Dept;
import zze.springcloud.service.DeptClientService;
import java.util.List;
/**
* 当 DeptClientService 的某方法调用异常时会回调下面实现 DeptClientService 的方法
*/
@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory<DeptClientService> {
@Override
public DeptClientService create(Throwable throwable) {
return new DeptClientService() {
@Override
public Dept get(Long id) {
return new Dept().setDeptNo(id).setDeptName("该部门不存在").setDbSource("数据源中没有这个部门");
}
@Override
public List<Dept> list() {
return null;
}
@Override
public boolean add(Dept dept) {
return false;
}
};
}
}
zze.springcloud.service.fallback.DeptClientServiceFallBackFactory
3、修改 Feign 客户端接口类,指定回调工厂类:
package zze.springcloud.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import zze.springcloud.entities.Dept;
import zze.springcloud.service.fallback.DeptClientServiceFallBackFactory;
import java.util.List;
/*
value 表示要调用的微服务名称
fallbackFactory 指定调用失败时执行的熔断回调工厂类
*/
@FeignClient(value = "microservicecloud-provider-dept",fallbackFactory = DeptClientServiceFallBackFactory.class)
@RequestMapping("/dept")
public interface DeptClientService {
@GetMapping("/get/{id}")
public Dept get(@PathVariable("id") Long id);
@GetMapping("/list")
public List<Dept> list();
@PostMapping("/add")
public boolean add(Dept dept);
}
zze.springcloud.service.DeptClientService
4、修改配置文件,启用 Feign 的熔断功能:
server:
port: 80
eureka:
client:
service-url:
defaultZone: http://www.eurekaserver1.com:7001/eureka,http://www.eurekaserver2.com:7002/eureka,http://www.eurekaserver3.com:7003/eureka
instance:
instance-id: microservicecloud-provider-dept
prefer-ip-address: true # 访问路径显示 IP
spring:
application:
name: microservicecloud-consumer-dept
# 启用 feign 的熔断功能
feign:
hystrix:
enabled: true
application.yml
5、测试:
1、启动 7001、7002、7003 Eureka 集群 2、启动 Provider 服务 microservicecloud-provider-dept-8001 3、启动 Consumer 服务 microservicecloud-consumer-dept-80 4、访问 http://localhost/consumer/dept/get/1 ,正常返回信息 5、关闭 8001 Provider 服务,再次访问 http://localhost/consumer/dept/get/1 ,返回熔断回调工厂类中自定义的信息:

test
消费端(调用端)操作,从上面测试结果中可以看到即使 Provider 服务挂了,Consumer 也可以返回可处理的数据而不是随之挂掉。
豪猪HystrixDashboard
介绍
HystrixDashboard 是 Hystrix 提供的准实时的调用监控,Hystrix 会持续地记录所有通过 Hystrix 发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少次请求、多少成功、多少失败等。Netflix 通过 hystrix-metrics-events-stream 项目实现了对以上指标的监控。SpringCloud 也提供了 HystrixDashboard 的整合,对监控内容转化成可视化界面。
使用
1、新建名为 "microservicecloud-consumer-hystrix-dashboard" 的子工程作为监控微服务工程,添加相关依赖:
<!--Hystrix Dashboard 相关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
2、新建配置文件,配置占用端口:
server: port: 9001
application.yml
3、新建主启动类,使用注解添加监控支持:
package zze.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableHystrixDashboard // 开启监控支持
public class Application_9001 {
public static void main(String[] args) {
SpringApplication.run(Application_9001.class, args);
}
}
zze.springcloud.Application_9001
4、保证所有的 Provider 服务都添加了监控依赖:
<!--监控信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
5、测试监控服务自身是否正常:
启动 microservicecloud-consumer-hystrix-dashboard 服务,访问 http://localhost:9001/hystrix 如果出现下面页面则测试通过:

test
6、监控测试:
1、启动 7001、7002、7003 Eureka 集群 2、启动 microservicecloud-provider-dept-hystrix-8001 带有熔断功能的 Provider 服务 3、启动 microservicecloud-consumer-dept-80 消费者服务 4、启动 microservicecloud-consumer-hystrix-dashboard 监控服务 5、访问监控服务提供的可视化 web 页,http://localhost:9001/hystrix: 6、随后出现如下界面:

7、访问被监控的服务,会发现曲线会根据访问频率发生变化

test
java框架之SpringCloud(5)-Hystrix服务熔断、降级与监控的更多相关文章
- java框架之SpringCloud(1)-微服务及SpringCloud介绍
微服务概述 是什么 业界大牛 Martin Fowler 这样描述微服务: 参考[微服务(Microservices)-微服务原作者Martin Flower博客翻译]. 下面是关于上述博客中的部分重 ...
- dubbo学习实践(4)之Springboot整合Dubbo及Hystrix服务熔断降级
1. springboot整合dubbo 在provider端,添加maven引入,修改pom.xml文件 引入springboot,版本:2.3.2.RELEASE,dubbo(org.apache ...
- java框架之SpringCloud(3)-Eureka服务注册与发现
在上一章节完成了一个简单的微服务案例,下面就通过在这个案例的基础上集成 Eureka 来学习 Eureka. 介绍 概述 Eureka 是 Netflix 的一个子模块,也是核心模块之一.Eureka ...
- 【5】JMicro微服务-熔断降级
如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 1. 使用服务熔断降级特性,必须先启动Pubsub服务,服务监听服务,熔断器服务3个服务 先启动Pubsub及服务监听两 ...
- SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级
什么是Hystrix 在分布式环境中,许多服务依赖项中的一些服务依赖不可避免地会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务 ...
- SpringCloud实战-Hystrix请求熔断与服务降级
我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...
- springcloud组件之hystrix服务熔断,降级,限流
hystrix 简介 Hystrix是什么 在分布式环境中,许多服务依赖项中的一些必然会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互.Hystrix通过 ...
- Hystrix(服务熔断,服务降级)
一.Hystrix 1.服务雪崩 多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C有调用其他的微服务,这就是所谓的”扇出”,如扇出的链路上某个微服务的调用响应式过长或者 ...
- spring cloud 学习(4) - hystrix 服务熔断处理
hystrix 是一个专用于服务熔断处理的开源项目,当依赖的服务方出现故障不可用时,hystrix有一个所谓的断路器,一但打开,就会直接拦截掉对故障服务的调用,从而防止故障进一步扩大(类似中电路中的跳 ...
随机推荐
- Win10 calc.exe 无法打开计算器的解决方法
先将所有程序关闭,以管理员身份运行 Windows PowerShell,之后输入以下命令 Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage - ...
- .NET内存泄漏(之 静态事件)
一.事件引起的内存泄露 1.不手动注销事件也不发生内存泄露的情况 我们经常会写EventHandler += AFunction; 如果没有手动注销这个Event handler类似:EventHan ...
- 解决Chrome 70版本以后谷歌不再信任赛门铁克证书问题
Google 从 2018 年 10 月发布的 Chrome 70 就停止信任赛门铁克的旧证书了,而 Mozilla 也将在 10 月底发布 Firefox 63 时停止信任赛门铁克的旧证书. 导致大 ...
- 【转】JAVA反射与注解
转载自:https://www.daidingkang.cc/2017/07/18/java-reflection-annotations/ 前言 现在在我们构建自己或公司的项目中,或多或少都会依赖几 ...
- ant 通配符
ant 通配符 我们常用的匹配模式有ANT模式,比如acegi可以用PATTERN_TYPE_APACHE_ANT来使用ANT匹配模式,那什么是ANT匹配模式呢. ANT通配符有三种: 通 ...
- Linux 环境变量_006
***Linux 环境变量指系统运行程序或命令的能快速找到其位置等其它功能,不用输入复杂命令.以$PATH环境变量为例子, $PATH决定了shell指定寻找命令或程序的路径,比较执行ls命令,如果没 ...
- DBA-mysql-授权
权限系统介绍 权限系统的作用是授予来自某个主机的某个用户可以查询.插入.修改.删除等数据库操作的权限. 不能明确的指定拒绝某个用户的连接. 权限控制(授权与回收)的执行语句包括create user, ...
- MySQL命令学习
上面两篇博客讲了MySQL的安装.登录,密码重置,为接下来的MySQL命令学习做好了准备,现在开启MySQL命令学习之旅吧. 首先打开CMD,输入命令:mysql -u root -p 登录MySQ ...
- 如何免费下载付费音乐歌曲,6个网站+8个APP
现在听音乐的软件,QQ音乐,酷狗,网易云等,很多歌曲可以在线听. 但是下载某些歌曲或者在线听高品质无损的都需要付费. 这一期,给大家推荐的是免费下载付费歌曲工具,包括网站跟APP. 网站篇 1.VIP ...
- [原]Chef_Server and Chef_WorkStation and Chef_Client Install Guide[by haibo]
一.Prerequisite OS : CentOS-7.0-1406-x86_64-DVD.iso Time Server : NTP Server SERVER NAME IP PLAN ...