在每个服务中引用该组件,监控当前组件。可被GateWay、Fegin集成。
简介
作用:防止服务雪崩
Hystrix是一个由Netflix开源的容错框架,它主要用于分布式系统中的服务间通信。Hystrix通过在调用服务的过程中添加各种容错机制,来保护系统免受服务故障或网络中断的影响,从而提高了系统的可靠性和弹性。Hystrix提供了许多功能,例如超时控制、断路器、线程池隔离、请求缓存等等,它可以快速、可靠地为您的应用程序提供容错保护。
熔断器的原理很简单,如同电力过载保护器。它可以实现快速失败,如果它在一段时间内侦测到许多类似的错误,会强迫其以后的多个调用快速失败,不再访问远程服务器,从而防止应用程序不断地尝试执行可能会失败的操作,使得应用程序继续执行而不用等待修正错误,或者浪费 CPU时间。熔断器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。
Hystrix的主要功能包括:
- 快速失败(Fail Fast):当一个依赖服务出现故障时,Hystrix能够快速地中断请求,避免等待超时而浪费系统资源。
- 回退机制(Fallback):当一个依赖服务出现故障时,Hystrix能够提供回退逻辑,返回一个默认值或执行备选方案,从而保证系统的稳定性。
- 熔断器(Circuit Breaker):Hystrix能够自动地监控依赖服务的状态,当故障率达到一定阈值时,自动打开熔断器,防止请求继续发往不可用的依赖服务。
- 缓存(Cache):Hystrix能够提供缓存机制,避免对同一数据的重复请求,从而提高系统的性能。
- 隔离(Isolation):Hystrix能够通过线程池隔离、信号量隔离等机制,避免依赖服务的故障对系统的其他部分造成影响。
- 监控和度量(Monitoring and Metrics):Hystrix能够提供近乎实时的监控和度量,包括请求成功率、请求响应时间、熔断器状态等指标,从而帮助开发人员快速地定位和解决问题。
服务熔断
当满足一定的阈值的时候(默认10s内超过20个请求失败)
当失败率达到一定的时候(默认10s内50%的请求失败)
断路器将会开启
开启时,所有请求都不会进行转发
一段时间后(默认是5s),这个时候断路器是半开状态,会让其中一个请求进行转发,如果成功,断路器关闭,若失败,重复流程;
快速上手
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
在入口类添加注解
@EnableCircuitBreaker
服务端熔断
设置熔断后的快速反应(备用处理)
@GetMapping("demo")
@HystrixCommand(fallbackMethod = "demoFallback") //指定快速处理方案的方法名
public String demo(String id){
if(){
throw new RuntimeException("出错!");
}
}
public String demoFallback(String id){
}
-
阿,,,光处理异常的话,这种形式和直接catch里处理有什么区别,,是顺便加上了断路器的功能吗?
处理方法-“替身文学”
为每个方法都自定义处理方式,代码工作有些繁重,可以指定一个通用的默认的处理方法
@HystrixCommand(defaultFallback = "默认的处理")
默认的处理方法返回值为String,没有形参,因为要可以为不同的方法提供处理
如果使用自定义的处理方法,则该方法形参和返回值要和对应的Controller方法对应
相当于该方法的“替身”,当该服务不可用时,使用fallback方法
代餐
代为处理
注:用hystrix做服务端熔断,只有服务可用才能正常返回fallback处理,因为fallback处理也是该服务的一部分
消费端熔断
由Feign处理,假如整个服务断了,fallback都用不了,由Feign返回
熔断器触发机制
-
怎么记录?失败的请求怎么办
OpenFeign整合
-
openfeign和gateway重复了吧, - 阿我明白了,,,openfegin是项目内部调用,这部分本来就不走网关,,而另外那些要访问网关的(?)他们需要在网关进行处理才行
openfeign底层默认集成hystrix
开启openFeign对hystrix支持
feign.hystrix.enabled=true
在feign的client接口上
@FeignClient(value = "服务id",fallback=实现类.class)
然后编写bean实现该client接口,重写对应方法,加上组件注解
用工厂模式
以若依项目为例
@FeignClient(value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
编写工厂类,实现
FallbackFactory<T>
接口,重写create方法,返回一个内部类对象(毕竟工厂类要返回实体对象,但原client是个接口)
@Component
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService>
{
private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class);
@Override
public RemoteUserService create(Throwable throwable)
{
log.error("用户服务调用失败:{}", throwable.getMessage());
return new RemoteUserService()
{
@Override
public R<LoginUser> getUserInfo(String username, String source)
{
return R.fail("获取用户失败:" + throwable.getMessage());
}
@Override
public R<Boolean> registerUserInfo(SysUser sysUser, String source)
{
return R.fail("注册用户失败:" + throwable.getMessage());
}
};
}
整合GateWay过滤器
spring:
cloud:
gateway:
routes:
# 系统模块
- id: ruoyi-system
uri: lb://ruoyi-system
predicates:
- Path=/system/**
filters:
- StripPrefix=1
# 降级配置
- name: Hystrix
args:
name: default
# 降级接口的地址
fallbackUri: 'forward:/fallback'
然后自行实现fallback的controller
import org.gateway.response.Response;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FallbackController {
@GetMapping("/fallbackA")
public Response fallbackA() {
Response response = new Response();
response.setCode("100");
response.setMessage("服务暂时不可用");
return response;
}
}
上面配置包含了一个
Hystrix
过滤器,该过滤器会应用
Hystrix
熔断与降级,会将请求包装成名为
fallback
的路由指令
RouteHystrixCommand
,
RouteHystrixCommand
继承于
HystrixObservableCommand
,其内包含了
Hystrix
的断路、资源隔离、降级等诸多断路器核心功能,当网关转发的请求出现问题时,网关能对其进行快速失败,执行特定的失败逻辑,保护网关安全。配置中有一个可选参数
fallbackUri
,当前只支持
forward
模式的
URI
。如果服务被降级,请求会被转发到该
URI
对应的控制器。控制器可以是自定义的
fallback
接口;也可以使自定义的
Handler
,需要实现接口
org.springframework.web.reactive.function.server.HandlerFunction<T extends ServerResponse>
。
3、实现添加熔断降级处理返回信息
package com.ruoyi.gateway.handler;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.domain.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import java.util.Optional;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
/**
-
熔断降级处理
-
@author ruoyi
*/
@Component
public class HystrixFallbackHandler implements HandlerFunction
{
private static final Logger log = LoggerFactory.getLogger(HystrixFallbackHandler.class);@Override
public Mono handle(ServerRequest serverRequest)
{
Optional originalUris = serverRequest.attribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
originalUris.ifPresent(originalUri -> log.error(“网关执行请求:{}失败,hystrix服务降级处理”, originalUri));
return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR.value()).contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(JSON.toJSONString(R.fail(“服务已被降级熔断”))));
}
}
4、路由配置信息加一个控制器方法用于处理重定向的/fallback请求
package com.ruoyi.gateway.config;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import com.ruoyi.gateway.handler.HystrixFallbackHandler;
import com.ruoyi.gateway.handler.ValidateCodeHandler;
/**
* 路由配置信息
*/
@Configuration
public class RouterFunctionConfiguration
{
@Autowired
private HystrixFallbackHandler hystrixFallbackHandler;
@Autowired
private ValidateCodeHandler validateCodeHandler;
@SuppressWarnings("rawtypes")
@Bean
public RouterFunction routerFunction()
{
return RouterFunctions
.route(RequestPredicates.path("/fallback").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
hystrixFallbackHandler)
.andRoute(RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
validateCodeHandler);
}
}
Hystrix Dashborad 图形化监控
显示状态信息。不是很重要,不推荐专门学习
是不是有统一的微服务监控能取代?
引入dashborad依赖, 默认@EnableDiscoveryClient开启
erver.HandlerFunction`。