Hystrix
一、概念
- 故障蔓延:由于一个服务变慢或没有响应导致大量请求堆积,进而导致其他服务瘫痪。
为了解决上述问题,微服务架构中引入了熔断器的服务保护机制。
- 微服务中的熔断器:当被调用的方法没有响应,调用方法直接返回一个错误响应即可,而不是长时间的等待,这样避免调用时因为等待而线程一直得不到释放,避免故障在分布式系统间蔓延。
- Spring Cloud Hystrix :实现了熔断器、线程隔离等一系列服务保护功能。该功能也是基于Netflex的开源框架Hystrix实现的,该框架的目标在于通过控制那些远程访问系统、服务和第三方库的节点,从而对延迟和故障提供更加强大的容错能力。Hystrix具有服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并、服务监控等强大功能。
二、使用
1. 环境搭建
-
在消费端加入依赖:
spring-cloud-starter-netflix-hystrix
-
在入口类使用
@EnableCircuitBreaker
注解开启熔断器功能,也可以使用@SpringCloudApplication
注解来代替主类上的三个注解 -
在消费端调用远程服务的方法上添加注解:
@HystrixCommand(fallbackMethod="error",commandProperties={ @HystrixProperty(name="execution.isolation.thread.timeoutInMillisecond",value="1500") })
标记当前控制器方法采用Hystrix熔断机制,当远程服务出现了异常或超时,就会自动进行熔断。
- 属性fallbackMethod用于指定一个本地方法的名称,当服务熔断以后就会调用这个方法来替代服务提供者的响应信息。避免用户看到错误信息或无限等待。
- 属性commandProperties可以指定超时时间。
2. 服务降级
当某个服务熔断之后,服务端提供的服务不再被调用,此时由客户端自己准备一个本地的fallbackMethod回调,返回一个默认值来代表服务端的返回。
这种做法,虽然不能得到正确的返回结果,但至少保证了服务的可用,比直接抛出错误或服务的不可用要好得多,当然这需要根据业务场景来选择。
3. 异常熔断
我们在调用服务提供者时,我们会有可能抛出异常,默认情况下方法抛出了异常会自动进行服务降级,交给服务降级中的方法去处理;
当我们自己发生异常后,只需要在服务降级方法
中添加一个Throwable
类型的参数就能够获取到抛出的异常的类型,如下:
如果远程服务有一个异常抛出后我们不希望进入到服务降级方法中去处理,而是直接讲异常抛出给用户,那么我们可以在@HystrixCommand注解中添加忽略异常@HystrixCommand(fallbackMethod = "error", ignoreExceptions = { HttpServerErrorException.InternalServerError.class})
4. 自定义异常熔断器
我们也可以自定义类继承HystrixCommand
来实现自定义的Hystrix请求,在getFallback方法中调用getExecutionException方法来获取服务抛出的异常;
public class MyHystrixCommand extends HystrixCommand<String> {
private RestTemplate restTemplate;
private String url;
/**
* 定义一个有参构造(必须)由于弗雷没有无参构造因此子类必须使用有参构造
*/
public MyHystrixCommand(Setter setter, RestTemplate restTemplate, String url) {
super(setter);
this.restTemplate = restTemplate;
this.url = url;
}
/**
* 这个方法不能手动调用,Spring会自动调用这个方法来访问我们的服务提供者
*/
@Override
public String run() throws Exception {
return restTemplate.getForEntity(url,String.class).getBody();
}
/**
* 服务降级方法:当Spring自动调用run方法以后,如果服务出现了异常则自动调用这个服务降级方法来进行异常的熔断处理
*/
@Override
public String getFallback() {
//获取异常信息
System.out.println(super.getFailedExecutionException().getClass());
System.out.println(super.getFailedExecutionException().getMessage());
return "自定义异常熔断器熔断了服务";
}
}
5.Hystrix仪表盘监控
Hystrix仪表盘(Hystrix Dashboard):监控Hystrix的实时运行状态,通过查看Hystrix的各项指标信息,从而快速发现系统中的问题进而解决它。
这个功能我们可以在原来的消费者应用上添加,让原来的消费者具备Hystrix仪表盘功能,但一般的,微服务架构思想推崇服务的拆分,Hystrix Dashboard也是一个服务,所以通常会单独创建一个新的工程专用做Hystrix Dashboard服务。
消费端配置:
- 添加健康检查机制依赖包
spring-boot-starter-actuator
- 配置文件配置SpringBoot监控端点的访问权限:
#开启SpringBoot的健康检查机制的所有端口
management.endpoints.web.exposure.exclude=*
- 消费者启动服务,访问
http://localhost:80/actuator
看到http://localhost:80/actuator/hystrix.stream
可以放到浏览器打开看看。
Hystrix Dashboard 服务端:
- 创建一个普通的SpringBoot工程
- 添加相关依赖
spring-cloud-starter-netflix-hystrix-dashboard
- 入口类添加注解
@EnableHystrixDashboard
激活仪表盘功能 - 配置文件 application.properties 中指定服务端口号
server.port=9000
- 启动服务,进行访问
http://localhost:9000/hystrix
点击进入:
三、测试
1. 异常熔断
- provider:
- consumer:
- 结果:由于服务端的异常,消费端使用了熔断机制
2. 超时熔断
- provider:
- consumer:
- 结果:没有熔断机制的时候会一直等待15s,得到服务;
有熔断机制的时候调用error函数,进行服务降级。
3. 熔断器获得异常
- 服务端异常
- 结果:使用熔断机制并且输出异常信息
- 消费端异常
- 结果:使用熔断机制输出异常信息
4. 异常忽略
-
服务端
-
消费端
-
结果(错误直接暴露给用户)
5. 自定义异常熔断器
- 消费端
- 服务端没有异常时:得到服务端的响应
- 服务端有异常时:熔断机制服务降级