Spring Cloud Gateway自定义过滤器实战(观测断路器状态变化) (3)

接下来是StatePrinterGatewayFilterFactory.java,这里用不上什么配置,所以apply方法的入参也就没用上,需要注意的是通过Autowired注解拿到了reactiveResilience4JCircuitBreakerFactory,然后通过构造方法传递给了StatePrinterGatewayFilter实例:

package com.bolingcavalry.circuitbreakergateway.filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.stereotype.Component; @Component public class StatePrinterGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> { @Autowired ReactiveResilience4JCircuitBreakerFactory reactiveResilience4JCircuitBreakerFactory; @Override public String name() { return "CircuitBreakerStatePrinter"; } @Override public GatewayFilter apply(Object config) { return new StatePrinterGatewayFilter(reactiveResilience4JCircuitBreakerFactory); } }

最后是配置文件,完整的配置文件如下,可见我们将CircuitBreakerStatePrinter过滤器加了进来,放到最后:

server: #服务端口 port: 8081 spring: application: name: circuitbreaker-gateway cloud: gateway: routes: - id: path_route uri: :8082 predicates: - Path=http://www.likecs.com/hello/** filters: - name: CircuitBreaker args: name: myCircuitBreaker - name: CircuitBreakerStatePrinter

再次运行单元测试类CircuitbreakerTest.java,如下图红框所示,断路器状态已经打印出来,至此,我们可以精确把握断路器的状态变化了:

在这里插入图片描述

分析请求被filter漏掉的问题

有个很明显的问题,聪明睿智的您当然不会忽略:上图绿框中的连续四个响应,对应的断路器状态都没有打印出来,要知道,咱们的过滤器可是要处理每一个请求的,怎么会连续漏掉四个呢?

其实原因很容易推理出来:断路器CircuitBreaker的filter先执行,然后才是咱们的CircuitBreakerStatePrinter,而处于开启状态的断路器会直接返回错误给调用方,其后面的filter都不会执行了

那么问题来了:如何控制CircuitBreaker和CircuitBreakerStatePrinter这两个filter的顺序,让CircuitBreakerStatePrinter先执行?

CircuitBreakerStatePrinter是咱们自己写的代码,修改StatePrinterGatewayFilter.getOrder的返回值可以调整顺序,但CircuitBreaker不是咱自己的代码呀,这可如何是好?

老规矩,看看断路器的源码,前文已经分析过了,断路器最重要的代码是SpringCloudCircuitBreakerFilterFactory.apply方法,如下图红框,生成的filter是GatewayFilter接口的实现类:

在这里插入图片描述

再看加载过滤器到集合的那段关键代码,在RouteDefinitionRouteLocator.loadGatewayFilters方法中,如下图所示,由于CircuitBreaker的filter并没有实现Ordered接口,因此执行的是红框中的代码,代表其顺序的值等于i+1,这个i就是遍历路由配置中所有过滤器时的一个从零开始的自增变量而已:

在这里插入图片描述

回顾咱们的路由配置,CircuitBreaker在前,CircuitBreakerStatePrinter在后,所以,在添加CircuitBreaker的时候,i等于0,那么CircuitBreaker的order就等于i+1=1了

而CircuitBreakerStatePrinter实现了Ordered接口,因此不会走红框中的代码,其order等于咱们写在代码中的值,咱们写的是10

所以:CircuitBreaker的order等于1,CircuitBreakerStatePrinter等于10,当然是CircuitBreaker先执行了!

再次修改

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzdpfj.html