SpringCloud_learn04_Hystrix断路器
一、Hystrix断路器是什么
1.Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的可用性。
2.当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
3.主要作用:服务降级、服务熔断、服务限流、接近实时的监控等
二、服务熔断
1.熔断机制是应对雪崩效应的一种微服务链路保护机制。(服务端向客户端返回的异常兜底方案,也可以作为另一种抛出异常的解决方式,防止try/catch写多了方法膨胀。)
当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回"错误"的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand。
2.场景测试示例
2.1 套路 -- GAV+EnableXXX注解
在服务端的pom文件中添加GAV坐标
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
在服务端的主启动类上添加注解:@EnableCircuitBreaker
2.2 示例代码
@RequestMapping(value="/dept/get/{id}",method=RequestMethod.GET)
@HystrixCommand(fallbackMethod = "processHystrixGet")
public Dept get(@PathVariable("id") Long id)
{
Dept dept = service.get(id);
if(dept == null) {
throw new RuntimeException("no such dept");
}
return dept;
}
@SuppressWarnings("unused")
private Dept processHystrixGet(@PathVariable("id") Long id) {
return new Dept().setDeptno(id).setDname("hystrix -- no such dept: ["+ id +"]").setDb_source("no data");
}
2.3 测试
启动服务端 -- 启动客户端 -- 访问 http://localhost:8080/consumer/dept/get/12
返回: {"deptno":12,"dname":"hystrix -- no such dept: [12]","db_source":"no data"}
三、服务降级
1.整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
2.服务降级处理是在客户端实现完成的,与服务端没有关系
3.feign+hystrix完成服务降级
3.1 在feign抽取的接口处添加fallbackFactory属性值
@FeignClient(value = "cloud-provider", fallbackFactory = DeptClientServiceFallbackFactory.class)
3.2 在抽取的接口处,编写 DeptClientServiceFallbackFactory
package DeptClientServiceFallbackFactory;
import java.util.List;
import org.springframework.stereotype.Component;
import com.xx.discovery.entities.Dept;
import com.xx.discovery.service.DeptClientService;
import feign.hystrix.FallbackFactory;
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>{
@Override
public DeptClientService create(Throwable cause) {
return new DeptClientService() {
@Override
public List<Dept> list() {
// TODO Auto-generated method stub
return null;
}
@Override
public Dept get(long id) {
return new Dept().setDeptno(id)
.setDname("当前访问的服务已降级,请稍后重试")
.setDb_source("no data");
}
@Override
public boolean add(Dept dept) {
// TODO Auto-generated method stub
return false;
}
};
}
}
3.3 在客户端的yaml配置文件中添加feign对hystrix的配置依赖:
feign:
hystrix:
enabled: true
3.4 测试
直接运行客户端 访问:http://localhost:8080/consumer/dept/get/12
返回:{"deptno":12,"dname":"当前访问的服务已降级,请稍后重试","db_source":"no data"}
四、服务监控hystrixDashboard
除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功/失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。
1.hystrixDashboard工程搭建及单实例测试实践
1.1 pom文件GAV坐标
<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.xx.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>microservicecloud-consumer-hystrix-dashboard</artifactId>
<dependencies>
<!-- 自己定义的api -->
<dependency>
<groupId>com.xx.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- Ribbon相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- feign相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!-- hystrix和 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>
</dependencies>
</project>
若使用nacos替代eureka部分依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
1.2 application.yaml
server:
port: 9001
1.3 主启动类
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboard9001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboard9001.class, args);
}
}
1.4 带熔断的服务端pom文件添加:
<!-- actuator监控信息完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
1.5 启动hystrixDashboard工程
1.5.1 访问:localhost:9001/hystrix
1.5.2 访问带熔断(hystrix)服务的接口!localhost:8001/dept/get/1
1.5.3 填写信息
进入监控页面:
2.集群测试(以NACOS注册中心实践)
2.1 GAV坐标
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xx.discovery</groupId>
<artifactId>springcloud-nepxion-discovery</artifactId>
<version>1.0.1</version>
</parent>
<artifactId>cloud-hystrix-dashboard-9001</artifactId>
<dependencies>
<dependency><!-- 自己定义的api -->
<groupId>com.xx.discovery</groupId>
<artifactId>cloud-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 日志开始 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.1</version>
</dependency>
<!-- 日志结束 -->
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- Ribbon相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- feign相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!-- hystrix和 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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
<version>1.4.6.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-client
</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
2.2 yaml文件(添加了注册中心、被监控的服务名称配置)
server: port: 9001 spring: application: name: spring-cloud-hystrix-turbine cloud: nacos: discovery: server-addr: 127.0.0.1:8848 turbine: aggregator: #监控所有微服务集群 #hytrix仪表盘:http://localhost:8810/hystrix/ #监控地址:http://localhost:8810/turbine.stream #在hystrix仪表盘中监控上面的地址即可 clusterConfig: default #要监控的微服务serviceId appConfig: cloud-provider clusterNameExpression: "'default'"
2.3 主启动类
@EnableTurbine
2.4 测试
2.4.1启动hystrixDashboard工程
2.4.1 访问:localhost:9001/hystrix
2.4.2 访问带熔断(hystrix)服务的接口!localhost:8001/dept/get/1、localhost:8002/dept/get/1、localhost:8003/dept/get/1
2.4.3 填写信息
监控页面:
3.遇到的问题
3.1 hystrix.stream一直是ping,dashboard一直loading -> 解决方法:hystrix.stream一直是ping 最重要的是,在测试的时候,请求的方法一定要是加hystrix的!否则,dashboard检测不到hystrix监控流。
3.2 Expecting a 'String' but got a 'Mapping' node
3.2.1 问题出现原因,点击了create metadata for feign.hystrix
3.2.2 解决方法:
3.2.2.1 删除该目录下的META-INF文件夹
3.2.2.2 重启开发工具,update maven project