当分布式系统中的网关接收到大量请求并向后端远程系统或服务发起调用时,后端服务可能会产生调用失败(如超时或异常)。这时,如果让请求继续堆积在网关上,可能会导致整个系统的瘫痪。因此,需要快速失败并返回请求,这就是所谓的熔断。
降级是指在系统资源不足或者异常流量过大的情况下,通过限制部分功能或服务的使用,保证系统核心功能的正常运行
熔断降级可以看作是一种保护机制,当后端服务出现问题时,网关能够及时切断请求,避免问题在系统中扩散,同时提供降级服务,以尽可能减少对用户的影响。
在Spring Cloud Gateway中,可以通过配置Hystrix GatewayFilter来实现熔断降级。Hystrix是一个用于处理分布式系统中延迟和故障的库,它可以检测远程服务的故障,并在服务不可用时自动触发熔断器,以保护系统不受影响。同时,Hystrix还允许定义降级策略,当服务出现故障时,可以回退到备用逻辑或提供降级功能,以避免系统完全中断。
Spring Cloud Gateway 集成Hystrix
1、添加Hystrix 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、配置文件配置
server:
port: 8082
spring:
application:
name: gateway
redis:
host: localhost
port: 6379
password: 123456
cloud:
gateway:
routes:
- id: rateLimit_route
uri: http://localhost:8000
order: 0
predicates:
- Path=/test/**
filters:
# 指定使用HystrixGatewayFilterFactory生成filter
- name: Hystrix
args:
# 指定hystrix command的名称
name: defaultfallback
# 配置降级转发的接口,注意fallbackUri要以forward开头
fallbackUri: forward:/defaultfallback
# 设置hystrix 隔离策略,下面是hystrix 信号量隔离,1.5秒后自动超时
hystrix:
command:
default:
execution:
isolation:
#隔离策略
strategy: SEMAPHORE
thread:
#超时时间,单位为毫秒
timeoutInMilliseconds: 3000
过滤器Hystrix,作用是通过Hystrix进行熔断降级
当上游的请求,进入了Hystrix熔断降级机制时,就会调用fallbackUri配置的降级地址。需要注意的是,还需要单独设置Hystrix的commandKey的超时时间
fallbackUri配置的网关降级地址接口的代码如下,大家可以自定义自己的降级逻辑:
@RestController
public class FallbackController {
@GetMapping("/defaultfallback")
public Response defaultfallback() {
Response response = new Response();
response.setCode("100");
response.setMessage("服务暂时不可用");
return response;
}
}
我们要为fallbackUri编写一个用于降级的controller方法,并在配置文件中配置
Hystrix资源隔离策略
Hystrix的隔离策略有两种:分别是线程隔离和信号量隔离。
THREAD(线程隔离):线程隔离是Hystrix的默认策略,它会为每个HystrixCommand命令分配一个独立的线程池,每个命令都会在单独的线程上执行,互不干扰,并发请求受线程池中线程数量的限制。
线程池隔离下每个命令在独立的线程中执行,通过限制并发线程数,可以保护应用程序免受故障服务的慢速或错误响应的影响。线程池隔离提供了更好的资源隔离和保护,但也需要更多的资源开销。
SEMAPHORE(信号量隔离):信号量隔离是一种基于计数器的隔离策略,使用该方式,HystrixCommand将会在调用线程上执行,通过为每个hystrix命令分配一个独立的计数器来控制并发访问的数量。当并发请求达到一定阈值时,超出的请求会被拒绝,并发请求受信号量的个数的限制。
SEMAPHORE模式下所有的命令在同一个线程中执行,共享相同的线程池,通过限制并发访问数来保护应用程序。信号量隔离提供了更低的资源消耗,但是当依赖服务发生故障时,可能会导致整个应用程序的阻塞。
大家按照自己的需求选择合适的隔离策略