1、Hystrix介绍
雪崩:微服务架构中服务与服务之间会相互调用,相互依赖,如果由于网络或其他原因导致某个微服务的调用响应时间过长或不可用,大量请求进来可能就会导致系统资源占用过多,从而引起系统崩溃,也就是所谓的“雪崩效应”。
Hystrix是一个用于处理分布式系统的延迟和容错的 框架,当系统中某个服务发生故障或当调用一个特定的服务达到一定阈值(默认5秒失败20次) 后,通过断路器的故障监控,会返回一个FallBack响应,而不是长时间的等待,这样就保证了服务调用方的线程不会长时间占用,避免故障蔓延。
在分布式环境中,不可避免地会有许多服务依赖性失效。Hystrix是一个库,它通过添加延迟容忍和容错逻辑来帮助控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点,停止它们之间的级联故障,并提供回退选项,所有这些都提高了系统的整体弹性。
Hystrix被设计为如下作用:
从第三方客户端库访问(通常在网络上)的依赖关系来保护和控制延迟和失败。
在复杂的分布式系统中停止级联故障。
快速失败并迅速恢复。
如果可能的话,退后并优雅地降级。
启用近实时监控、报警和操作控制。
官方文档:
https://github.com/Netflix/Hystrix/wiki
https://projects.spring.io/spring-cloud/spring-cloud.html#_circuit_breaker_hystrix_clients
http://cloud.spring.io/spring-cloud-static/Edgware.SR4/single/spring-cloud.html
以下内容是基于上一节的工程,使用Hstrix实现服务熔断、服务降级、监控等。
源码下载:https://github.com/hnyydp/microservice
2、Hystrix与Ribbon整合
(1)、复制microservice-dept-consumer-80 新建一个消费者module模块 microservice-dept-consumer-ribbon-hystrix
,添加Hystrix依赖
pom.xml
<!-- Hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
(2)、修改配置
spring:
application:
name: microservice-dept-consumer-ribbon-hystrix
server:
context-path: /
port: 80
eureka:
client:
service-url:
#集群配置
defaultZone: http://eureka-server-5001.com:5001/eureka/,http://eureka-server-5002.com:5002/eureka/,http://eureka-server-5003.com:5003/eureka/
instance:
instance-id: microservice-dept-consumer80 #自定义服务名称信息
prefer-ip-address: true #访问路径上会显示IP,当应用程序向eureka注册时,它将使用其IP地址而不是其主机名。
(3)、在DeptConsumerController.java
中添加@HystrixCommand
注解,在fallbackMethod
中定义服务调用失败后回调的方法。
@GetMapping("/depts")
@HystrixCommand(fallbackMethod="fallBack_depts")
public List<Dept> depts() {
return restTemplate.getForObject(URL_PREFIX + "/depts", List.class);
}
@GetMapping("/dept/{id}")
@HystrixCommand(fallbackMethod = "fallBack_dept")
public Dept dept(@PathVariable(value = "id") Integer id) {
Dept dept = restTemplate.getForObject(URL_PREFIX + "/dept/" + id,
Dept.class);
// 模拟产生异常,Hystrix实现服务熔断
// 当服务调用抛出异常时,会自动调用@HystrixCommand中指定的fallback的方法
if (dept == null) {
throw new RuntimeException("没有找到ID:" + id + "对应的部门信息!");
}
return dept;
}
// 异常传入回退方法
public Dept fallBack_dept(@PathVariable(value = "id") Integer id) {
Dept dept = new Dept();
return dept.setDeptId(id).setDeptName("没有找到ID:" + id + "对应的部门信息!");
}
// 服务超时或中断
public List<Dept> fallBack_depts()
return ValueUtil.toList(new Dept().setDeptId(500).setDeptName(
"Error --- 服务异常"));
}
(4)、在主启动类DeptConsumerRibbonHystrixApplication.java
中开启Hystrix
@EnableCircuitBreaker //开启Hystrxi断路器,也可以用@EnableHystrix
@EnableEurekaClient
@SpringBootApplication
//@SpringCloudApplication //可以只使用这个,已经包括前面三个注解
public class DeptConsumerRibbonHystrixApplication {
public static void main(String[] args) {
SpringApplication.run(DeptConsumerRibbonHystrixApplication.class, args);
}
}
(5)、分别启动Eureka服务、服务提供者、消费者,模拟访问一个不存在的数据,停止服务提供者。
3、Hystrix与Feign整合
(1)、Feign是自带断路器的 ,修改microservice-common
,在@FeignClient
中增加fallbackFactory,用来统一管理fallback回调方法,
//也可以使用fallback属性,创建一个DeptClientService实现类管理fallback回调方法
//使用fallbackFactory可以获取异常Throwable
@FeignClient(value = "MICROSERVICE-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class) // 指定调用哪个服务
public interface DeptClientService {
(2)创建DeptClientServiceFallbackFactory.java
实现FallbackFactory接口
@Component //注入容器
public class DeptClientServiceFallbackFactory implements
FallbackFactory<DeptClientService> {
@Override
public DeptClientService create(Throwable e) {
return new DeptClientService() {
@Override
public Dept update(Dept dept) {
// TODO Auto-generated method stub
return null;
}
@Override
public Dept insert(Dept dept) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<Dept> depts() {
// TODO Auto-generated method stub
return null;
}
@Override
public Dept dept(Integer id) {
return new Dept().setDeptId(500).setDeptName(
"Error,调用服务异常!" + e.getMessage());
}
@Override
public boolean delete(Integer id) {
// TODO Auto-generated method stub
return false;
}
};
}
}
(3)、修改microservice-dept-consumer-feign
,在配置文件中启动fegin中Hystrix功能,然后分别启动Eureka服务、服务提供这、主启动类
# To disable Hystrix in Feign
feign:
hystrix:
enabled: true
4、Hystrix Dashboard 仪表盘
SpringCloud提供一个准实时的调用监控组件,可以以报表和图形化的形式展示。
(1)、创建一个监控服务microservice-hystrix-dashboard-9001
模块,添加相应依赖:
<!--actuator监控组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!-- Hystrix Dashboard-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
(2)、配置application.yml配置文件
spring:
application:
name: microservice-hystrix-dashboard
server:
context-path: /
port: 9001
(3)、在主启动类上添加@EnableHystrixDashboard
,开启断路器仪表盘功能
@EnableHystrixDashboard //开启断路器仪表盘功能
@SpringBootApplication
public class HystrixDashboradApplication_9001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboradApplication_9001.class, args);
}
}
(4)、启动主启动类,访问http://localhost:9001/hystrix.stream,就可以进入仪表盘页面
(5)、在服务提供者microservice-dept-provider-8001(8002,8003)
中加入spring-boot-starter-actuator
依赖,就会自动开启监控。
启动Eureka服务和服务提供者,启动消费者microservice-dept-consumer-ribbon-hystrix
访问http://localhost/consumer/dept/1,将服务加入仪表盘中:http://localhost:80/hystrix.stream
6、集群监控
Hystrix Turbine将每个服务Hystrix Dashboard数据进行了整合 ,通过turbine可以把所有服务的hystrix.stream聚合到一起,可以进行整体监控。
(1)、创建一个Turbine监控服务microservice-hystrix-dashboard-turbine-9002
模块,并添加turbine相应依赖:
<!--actuator监控组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!-- Hystrix Dashboard -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<!-- Turbine -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
(2)添加turbine配置
spring:
application:
name: microservice-hystrix-dashboard-turbine
server:
context-path: /
port: 9002
eureka:
client:
service-url:
#集群配置
defaultZone: http://eureka-server-5001.com:5001/eureka/,http://eureka-server-5002.com:5002/eureka/,http://eureka-server-5003.com:5003/eureka/
turbine:
app-config: microservice-dept-consumer-ribbon-hystrix #监控哪些服务,多个用“,”分割
cluster-name-expression: new String("default") #指定了集群名称为default
aggregator:
cluster-config: default #指定聚合哪些集群,多个使用","分割,默认为default。可使用
(3)、在主启动类TurbineDashboradApplication_9002.java
中添加@EnableTurbine
开启turbine
@EnableTurbine //开启Turbine, 只会监控有Hystrix的服务
@EnableHystrixDashboard //开启断路器仪表盘功能
@SpringBootApplication
public class TurbineDashboradApplication_9002 {
public static void main(String[] args) {
SpringApplication.run(TurbineDashboradApplication_9002.class, args);
}
}
(4)启动Eureka服务和服务提供者,启动消费者microservice-dept-consumer-ribbon-hystrix
访问http://localhost/consumer/dept/1,http://localhost:9002/hystrix.stream
将服务加入仪表盘中:http://localhost:9002/turbine.stream