目录
4.2 在application.yml里增加Resilience4j的配置
1、为什么要使用断路器?
在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC)。那么,为了保证其高可用,单个服务又必须进行集群部署。但由于网络原因或者自身的原因,服务并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪,甚至导致服务“雪崩”。
而预防或减少服务的雪崩,我们可以有几个应对的策略:
1.流量控制
2.改进缓存模式
3.服务自动扩容
4.服务调用者降级服务
而这一次,所要讲的是第4种的方法,即服务调用者降级服务,也可以说是熔断机制。
2、什么是熔断机制?
熔断机制,就是下游服务出现问题后,为保证整个系统正常运行下去,而提供一种降级服务的机制,通过返回缓存数据或者既定数据,避免出现系统整体雪崩效应。在SpringCloud中,该功能可通过配置的方式加入到项目中。
3、断路器的机制
断路器很好理解, 当请求后端服务失败数量超过一定比例(比如50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(比如5秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN).。断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力。
4、Resilience4j的使用
4.1 引入依赖jar包
<!--resilience4j-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
<!--resilience4j 配置文件支持,版本需要和Spring cloud中的匹配-->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.1.0</version>
</dependency>
4.2 在application.yml里增加Resilience4j的配置
resilience4j.circuitbreaker:
configs: #通用配置
default: # 断路器系统默认配置
#失败率,错误率达到或高于该值则进入open状态
failureRateThreshold: 50
#慢调用阀值,请求执行的时间大于该值时会标记为慢调用
slowCallDurationThreshold: 60s
#慢调用熔断阀值,当慢调用率达到或高于该值时,进入open状态
slowCallRateThreshold: 100
#状态滚动收集器大小,close状态时收集多少请求状态,用于计算失败率。
slidingWindowSize: 100
#状态收集器类型
#COUNT_BASED:根据数量计算,slidingWindowSize为次数
#TIME_BASED:根据时间计算,slidingWindowSize为秒数
slidingWindowType: COUNT_BASED
#计算错误率的最小请求数,不足最小调用次数不会触发任何变化。
minimumNumberOfCalls: 10
#是否自动进入halfOpen状态,默认false-一定时间后进入halfopen,ture-需要通过接口执行。
automaticTransitionFromOpenToHalfOpenEnabled: false
#进入halfOpen状态时,可以被调用次数,就算这些请求的失败率,低于设置的失败率变为close状态,否则变为open。
permittedNumberOfCallsInHalfOpenState: 10
#open状态变为half状态需要等待的时间,即熔断多久后开始尝试访问被熔断的服务。
waitDurationInOpenState: 60s
#事件缓冲区大小??
eventConsumerBufferSize: 10
#被计为失败的异常集合,默认情况下所有异常都为失败。
recordExceptions:
- java.lang.Exception
#不会被计为失败的异常集合,优先级高于recordExceptions。
ignoreExceptions:
- java.lang.IllegalStateException
instances: #熔断器类型
aCustomizer: #使用默认配置
baseConfig: default
cacheCustomizer: #自定义配置
failureRateThreshold: 10
4.3 加载自定义配置
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args){
SpringApplication.run(GatewayApplication.class, args);
}
/**
* 初始化断路器,读取Resilience4J的yaml配置
* @param circuitBreakerRegistry
* @return
*/
@Bean
public ReactiveResilience4JCircuitBreakerFactory reactiveResilience4JCircuitBreakerFactory(
CircuitBreakerRegistry circuitBreakerRegistry) {
ReactiveResilience4JCircuitBreakerFactory factory = new ReactiveResilience4JCircuitBreakerFactory();
//自定义断路器配置
// CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom().slidingWindowSize(100).build();
//设置断路器默认配置
//不修改默认值可以忽略
factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
//默认超时规则,默认1s,不使用断路器超时规则可以设置大一点
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(60000)).build())
//默认断路器规则
// .circuitBreakerConfig(circuitBreakerConfig).build())
.build());
//添加自定义拦截器
factory.configureCircuitBreakerRegistry(circuitBreakerRegistry);
return factory;
}
}
4.4 修改application.yml配置
server:
port: 80
spring:
application:
name: test-gateway
security:
user:
name: test
password: 123456
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]': # 匹配所有请求
allowedOrigins: "*" #跨域处理 允许所有的域
allowedMethods: # 支持的方法
- GET
- POST
- PUT
- DELETE
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
#路径匹配
- id: find
uri: https://blog.csdn.net # 测试
predicates:
- Path=/csdn/**
filters:
- StripPrefix=1 #去掉Path前缀,参数为1代表去掉/csdn
- RL #注意:RLGatewayFilterFactory,只需要写RL
- name: CircuitBreaker #使用resilience4j断路器
args:
name: cacheCustomizer #自定义断路器配置
fallbackUri: forward:/cache/timestemp #异常跳转
eureka:
instance:
leaseRenewalIntervalInSeconds: 10
health-check-url-path: /actuator/health
hostname: 127.0.0.1
client:
registryFetchIntervalSeconds: 5
service-url:
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:8001/eureka/
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS