微服务实践(七)熔断降级
服务熔断降级概念
服务熔断和服务降级是分布式系统中常见的容错机制。
服务熔断指的是在一段时间内,如果一个服务的请求失败率超过了设定的阈值,系统就会自动短路,不再调用该服务,而是直接返回错误响应或者调用 fallback 逻辑,以减少对该服务的负载,防止服务雪崩的发生。当服务熔断后,当服务调用出现问题时,服务消费方可以快速响应,避免等待超时和资源浪费。
服务降级是指当服务的某个功能出现故障或异常时,提供一个备用的功能来代替原始功能,保证服务可用性。
熔断降级框架
Hystrix
Hystrix是Netflix开源的一款熔断降级框架,功能非常丰富,包括线程池隔离、信号量隔离、熔断、降级等。但是Hystrix的维护已经停止,不再提供新的功能和Bug修复。
1.在 pom.xml
文件中添加 的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>{version}</version>
</dependency>
2.在FeignClient接口的注解中添加fallback
属性,指定降级类,例如:
@FeignClient(name = "user-service", fallback = UserFallbackFactory.class)
public interface UserFeignClient {
@GetMapping("/users/{id}")
User findById(@PathVariable Long id);
}
@Component
public class UserFallbackFactory implements FallbackFactory<UserFeignClient> {
@Override
public UserFeignClient create(Throwable cause) {
return new UserFeignClient() {
@Override
public UserfindById() {
// 降级逻辑
return new User(id, "default", "123456");
}
};
}
}
3.在配置文件中添加Hystrix的相关配置,例如:
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 # 设置超时时间
circuitBreaker:
enabled: true # 开启熔断
requestVolumeThreshold: 10 # 熔断请求阈值
errorThresholdPercentage: 60 # 错误率阈值
sleepWindowInMilliseconds: 5000 # 熔断器开启时间
4.开启Hystrix的Feign支持,如下所示:
feign:
hystrix:
enabled: true
5.这样就完成了熔断的配置。
注意:Hystrix相关依赖和配置写在调用方,它是用于熔断和降级的功能,这些功能通常是由调用方控制和触发的。被调用方可能没有意识到是否需要熔断或降级
下面是Hystrix熔断器的一些常见配置参数及其含义:
circuitBreaker.enabled
: 是否启用断路器,默认为 true。circuitBreaker.requestVolumeThreshold
: 在滚动时间窗口中,请求数量的阈值,达到该阈值后才会进行熔断计算。默认为 20。circuitBreaker.errorThresholdPercentage
: 断路器打开的错误百分比阈值,默认为 50。circuitBreaker.sleepWindowInMilliseconds
: 断路器打开后,在该时间窗口内,所有请求都将直接返回失败(即被降级或者抛出异常),而不会尝试执行远程调用。默认为 5000 毫秒。metrics.rollingStats.timeInMilliseconds
: 滚动时间窗口的持续时间(以毫秒为单位),用于统计断路器指标的时间跨度。默认为 10000 毫秒。metrics.rollingStats.numBuckets
: 滚动时间窗口被分成的桶数,默认为 10。execution.isolation.thread.timeoutInMilliseconds
: 服务调用的超时时间,默认为 1000 毫秒。fallback.enabled
: 是否启用服务降级,默认为 true。fallback.isolation.semaphore.maxConcurrentRequests
: 当服务降级启用时,最大的并发降级请求数,默认为 10。requestCache.enabled
: 是否启用请求缓存,默认为 true。
以上只是一部分常用的配置参数,更多详细的配置参数可以参考Hystrix 官方文档 。
2.Resilience4j
在 Spring Cloud 2020 版本之后,Spring Cloud 对 OpenFeign 进行了更新,官方提供了一种新的方式来实现服务熔断,即通过 Resilience4j
库实现。相较于 Hystrix,Resilience4j 是一个轻量级的库,它具有更快的性能,更好的扩展性,更多的配置项,以及更好的响应式支持。下面简单介绍一下如何使用:
1.添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-cloud2</artifactId>
<version>1.7.0</version>
</dependency>
2.配置文件启用circuitbreaker
spring:
application:
name: user-service
cloud:
circuitbreaker:
enabled: true # 开启 Resilience4j
feign:
hystrix:
enabled: false # 关闭 Hystrix
3.定义 Feign
接口
@FeignClient(name = "user-service", fallback = UserFallbackFactory.class)
public interface UserFeignClient {
@GetMapping("/users/{id}")
User findById(@PathVariable Long id);
}
4.定义降级逻辑
@Component
public class UserFallbackFactory implements FallbackFactory<UserFeignClient> {
@Override
public UserFeignClient create(Throwable cause) {
return new UserFeignClient() {
@Override
public UserfindById() {
// 降级逻辑
return new User(id, "default", "123456");
}
};
}
}
5.配置熔断器
@Configuration
public class CircuitBreakerConfig {
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> globalCustomConfiguration() {
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
.failureRateThreshold(50)
.waitDurationInOpenState(Duration.ofSeconds(10))
.ringBufferSizeInClosedState(100)
.build();
return factory -> {
factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.circuitBreakerConfig(circuitBreakerConfig)
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(5)).build())
.build());
factory.addCircuitBreakerCustomizer(cb -> cb.getEventPublisher()
.onStateTransition(event -> System.out.println("Circuit breaker " + event.getCircuitBreakerName()
+ " changed state from " + event.getStateTransition().getFromState()
+ " to " + event.getStateTransition().getToState())));
};
}
}
在上面的示例中,我们通过 CircuitBreakerConfig
配置了熔断器的参数,然后通过 Customizer
对象全局配置了 Resilience4j 的断路器,包括熔断器和限流器。在 CircuitBreakerConfig
类中,我们还注册了一个熔断器事件监听器,可以监听熔断器状态的变化。在 Feign 接口中,我们通过 fallback
属性指定了降级逻辑类,在服务不可用时会执行该类的降级逻辑。
Resilience4JCircuitBreakerFactory的常用配置项解读:
- CircuitBreakerConfig: 配置熔断器的参数,例如故障率、时间窗口等。包括以下参数:
failureRateThreshold
:故障率阈值,默认值为50,表示当请求的失败率超过50%时,触发熔断器的open状态slowCallRateThreshold
:慢调用率阈值,默认值为100,表示当慢调用率(慢调用指的是耗时超过阈值的调用)超过100%时,触发熔断器的open状态permittedNumberOfCallsInHalfOpenState
:半开状态下允许的最大请求次数,默认值为10slidingWindowSize
:滑动窗口大小,默认值为100minimumNumberOfCalls
:最小请求数量,默认值为100,当请求数量小于此值时,熔断器不会打开waitDurationInOpenState
:open状态持续时间,默认为60秒automaticTransitionFromOpenToHalfOpenEnabled
:是否允许open状态自动转换为half-open状态,默认为truewritableStackTraceEnabled
:是否允许记录异常栈信息,默认为false
- TimeLimiterConfig:配置时间限制器的参数,包括以下参数:
timeoutDuration
:调用超时时间,默认为1秒
- BulkheadConfig:配置隔离器的参数,包括以下参数:
maxConcurrentCalls
:最大并发请求数,默认为25maxWaitDuration
:最大等待时间,默认为0,表示无限等待maxQueueSize
:等待队列大小,默认为100
- RetryConfig:配置重试的参数,包括以下参数:
maxAttempts
:最大重试次数,默认为3waitDuration
:重试等待时间,默认为500msretryExceptions
:需要重试的异常类型,默认为全部异常类型
Leave a Reply