SpringCloudGateway知识点梳理

SpringCloudGateway知识点梳理

一、工作流程


路由、谓词、拦截器关系

Spring Cloud Gateway核心处理流程

二、yml配置

spring:
  cloud:
    gateway:
      routes:
      - id: middleground
        uri: http://192.168.1.187:9990
        predicates:
        - Path=/middleground/**
        filters:
        - Pre
      - id: httpproxy
        uri: http://127.0.0.1:8080
        predicates:
        - Path=/study/**
        filters:
        - Pre=myxxx, 123456
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin Access-Control-Allow-Methods Access-Control-Allow-Headers Vary
      - id: httpproxy2
        uri: http://127.0.0.1:8080
        predicates:
        - Path=/study2/**
        filters:
        - Pre=myyyy, 987654321

三、源码分析

1、过滤器源码

上面配置有两个路由,PreGatewayFilterFactory是自定义的过滤器;在spring容器启动的时候会进行对象实例化,同时该对象的public GatewayFilter apply(Config config);在实例化之后,会先行被调用,每个路由会有自己的配置,apply会被调用多次,调用之后会返回;
RouteDefinitionRouteLocator对象的属性gatewayFilterFactories中存放了已经实例化的GatewayFilterFactory对象,包含自定义的;

比较重要的两个类

http调用过程
org.springframework.cloud.gateway.handler.FilteringWebHandler会存放filters属性,FilteringWebHandler根据请求得到对应的Route,从而得到这个路由对应到的GatewayFilter,将全局的过滤器与这个路由的过滤器进行排序得到一个有序的过滤器集合,根据这个过滤器集合创建一个DefaultGatewayFilterChain对象,然后filter(exchange)
过滤执行链,类设计图

这种实现,可以在一个方法内部实现前后处理
org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping 会调用lookupRoute方法,
这个对象中有一个routeLocator对象,这个里面有所有的路由,对所有路由进行遍历,找到相应的路由,再去调用GatewayFilter

2、返回Mono对象说明


返回的内容如上图,形成一个多层嵌套的Mono对象,就实现了后处理,除了then,还可能在之前有doOnNext操作,放在doOnNext或then中都可以达到后操作的目的。分析是这样,但是实际验证,当求改http响应头,在then中才有效,在doOnNext没生效,因为doOnNext根本就没有触发,是因为返回的全是Mono没有元素发出,所以doOnNext才没有生效。

3、过滤器执行顺序

在yml针对某个路由,按照先后顺序定义过滤器,如果这个过滤器实现没有定义顺序的话,就按照定义的先后顺序来执行,是因为针对没有实现接口的GatewayFilter会被重写包装为一个OrderedGatewayFilter对象,在这过程中自动将顺序递增的,后面进行排序,所以就有先后执行,如果需要设置过滤器的执行顺序,需要实现Ordered接口,是里利用这个接口获取到顺序,重写包装为OrderedGatewayFilter对象使用的序号就不是自增的,而是通过Ordered接口得到的。

四、谓词使用

参考官方文档

五、过滤器使用

  • DedupeResponseHeaderGatewayFilterFactory 针对响应头进行去重,当进行跨域处理的时候,服务实现了跨域处理,但是在网关也进行了跨域处理,双重处理之后,响应头会有问题,这里进行响应头去重;这里的写法是采用空格分割,是因为代码底层就是采用空格进行分割的(但是整个内容都是name属性值),如下图

    参考官方文档

六、参考

[1] Spring Cloud Gateway 过滤器详解 https://blog.csdn.net/leesinbad/article/details/127975661
[2] SpringCloudGateway官方文档 https://docs.spring.io/spring-cloud-gateway/docs/3.1.5/reference/html/
[3] Mono的官方文档,含有对应的方法解释图片
[4] 分布式网关概念及Spring Cloud Gateway动态路由实现 https://blog.csdn.net/solihawk/article/details/129680673
[5] SpringCloudGateway路由定义存至Mysql数据库 https://blog.csdn.net/yucaifu1989/article/details/128529299

posted @ 2023-12-13 10:38  理舞  阅读(181)  评论(0)    收藏  举报