一. 服务降级介绍
- 概念:服务降级一般是指在服务器压力剧增的时候,根据实际业务使用情况以及流量,对一些服务和页面有策略的不处理或者用一种简单的方式进行处理,从而释放服务器资源的资源以保证核心业务的正常高效运行。
- 原因: 服务器的资源是有限的,而请求是无限的。在用户使用即并发高峰期,会影响整体服务的性能,严重的话会导致宕机,以至于某些重要服务不可用。故高峰期为了保证核心功能服务的可用性,就需要对某些服务降级处理。可以理解为舍小保大
- 应用场景: 多用于微服务架构中,一般当整个微服务架构整体的负载超出了预设的上限阈值(和服务器的配置性能有关系),或者即将到来的流量预计会超过预设的阈值时(比如双11、6.18等活动或者秒杀活动)
服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的 fallback(退路)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。 - 需要考虑的问题:
区分哪些服务为核心,哪些为非核心
降级策略(处理方式,一般指如何给用户友好的提示或者操作)
自动降级还是手动降
二. 垄断器作用
- 当各服务应用在相互进行调用时,例如,B都调用C,而C服务奔溃,但是调用不会停止,相关的请求在不断的请求,是B的请求也在增多,会导致B服务崩溃,造成雪崩效应。
- 服务垄断是服务降级处理的一种方法。
三. 配置使用
3.1. 网关配置
在gateway的配置里添加相关的垄断配置。
# 针对全局配置
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 3000
如果需要对单个服务进行垄断配置
server:
port: 8080
spring:
application:
name: nchu-weather
cloud:
gateway:
routes:
- id: nchu-weather
uri: lb://nchu-weather
predicates:
- Path=/weather/**
filters:
- StripPrefix=1
# 降级配置
- name: Hystrix
args:
name: testOne
# 降级接口的地址
fallbackUri: forward:/fallback
# 针对全局配置
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 3000
# 对单独的 Hystrix 的 commandKey 设置超时时间
testOne:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
配置中有一个可选参数fallbackUri,当前只支持forward模式的URI。如果触发熔断,请求会被转发到该URI对应的控制器。控制器可以是自定义的fallback接口;也可以是自定义的Handler,需要实现接口org.springframework.web.reactive.function.server.HandlerFunction。
还设置了接口超时时间,也就是接口响应超过这个时间就会触发熔断。
3.2 自定义handler
自定义Handler
@Component
public class HystrixFallbackHandler implements HandlerFunction<ServerResponse>
{
private static final Logger log = LoggerFactory.getLogger(HystrixFallbackHandler.class);
@Override
public Mono<ServerResponse> handle(ServerRequest serverRequest)
{
Optional<Object> 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("{"error":"服务已被降级熔断"}")));
}
}
实现接口org.springframework.web.reactive.function.server.HandlerFunction。
@Configuration
public class RouterFunctionConfiguration
{
@Autowired
private HystrixFallbackHandler hystrixFallbackHandler;
@SuppressWarnings("rawtypes")
@Bean
public RouterFunction routerFunction()
{
return RouterFunctions
.route(RequestPredicates.path("/fallback").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
hystrixFallbackHandler);
}
}
如果不喜欢这类方式,可以直接去写一个控制器。