流程

我们用官方的图片来说明gateway的流程。当客户端访问gateway的时候,首先会通过DispatcherHandler#handle调用RoutePredicateHandlerMapping,也就是图中的Gateway Handler Mapping,然后再调用FilteringWebHandler,也就是图中的Gateway Web Handler。
我们从java8系列知道,java8的Predicate函数,用来表示一个涉及类型T的布尔表达式,RoutePredicateHandlerMapping也是类似的,当返回false的时候,说明不符合要求,所以他主要是用来判断路由是否匹配,不匹配就返回false。
FilteringWebHandler从名字上看就知道是用来处理过滤器的,从图上可以看出,他会有一个filter链,用来处理请求前和请求后的操作,类似zuul的pre和post。
image.png

Route

上面我们已经知道了gateway的流程,这个时候假设我们有多个URL,比如example.com/testA和example.com/testB过来,我们怎么知道哪些请求可以哪些请求不可以呢?我们可以用一个大的map来存储这些URL,但是我们如何针对某个URL进行特定的过滤请求呢,所以这样粗粒度控制是不行的。所以gateway是这样设计的:他为每个URL都配置了相应的规则和路由。如下图所示,每个路由Route都有自己的id,url,predicate以及gatewayFilters。
image.png
我们看到gatewayFilters是s结尾的,就猜到了他是集合,那predicate没有s,说明他只能带一个Predicate吗,其实不是的,java8的Predicate有or、and、negate的方法,他也是有的,所以他是这样设计的,当我们只有一个Predicate的时候:
image.png
当调用and方法,这样就有了两个Predicate,他的结构如下,他会把已有的Predicate放入left,再把新增的Predicate放入right。
image.png
当再调用and方法的时候,这个时候就有了3个Predicate,他的结构如下:
image.png
当然调用or也是类似的,他通过这样的结构,就可以实现和java8的Predicate一样的方法了。

RouteDefinition

上面已经知道了Route的结构,但是我们却不能直接在application.yml文件里配置,原因就是Predicate的复杂的结构,所以我们通过RouteDefinition来简化配置,RouteDefinition的结构如下:
image.png
可以看到,和Route的差别就是predicates和predicate的区别。每个集合的对象,都有一个name和map,map用来存放各种键值对用于判断是否符合以及过滤条件。比如我们的配置文件可以这样写:

spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: route1
          uri: https://www.examplea.com
          predicates:
            - After=2017-01-20T17:42:47.789-07:00[America/Denver]
            - Cookie=chocolate, ch.p
          filters:
            - AddRequestHeader=X-Request-red, blue
            - AddRequestParameter=red, blue
        - id: route2
          uri: https://www.exampleb.com
          predicates:
            - Path=/red/{segment},/blue/{segment}
            - Query=green
          filters:
            - AddResponseHeader=X-Response-Red, Blue
            - RewritePath=/consumingserviceendpoint, /backingserviceendpoint

RoutePredicateFactory

我们已经通过RouteDefinition去对应配置文件的配置信息,这些RouteDefinition最终还是要变成Route吧,配置的predicates、filters等最终也要变成Route的属性吧。在gateway中,用RoutePredicateFactory这个工厂类,通过配置信息,生成一个个Predicate。
系统中已经定义了十几个RoutePredicateFactory,然后放入map缓存中,他的key就是把类名中的RoutePredicateFactory去掉,比如我们上面配置的Path,可以知道他的工厂类就是PathRoutePredicateFactory。
所以我们在上面配置了多少个predicate,就有对应的工厂类给我们创建predicate,最后再组装成Route的Predicate结构,Predicate结构上面已经有图示了。

GatewayFilterFactory

既然Predicate有他的工厂类,根据配置信息生成不同的Predicate,Filter其实也是一样的。
系统也定义了很多个GatewayFilterFactory,放入map缓存中,他的key就是把类名中的GatewayFilterFactory去掉。比如我们上面配置的AddResponseHeader,可以知道他的工厂类就是AddResponseHeaderGatewayFilterFactory。这个设计方式和RoutePredicateFactory是一样的。

Locator

Locator是定位的意思,这里主要有两个Locator,一个是RouteLocator,一个是RouteDefinitionLocator,分别对应着上面的Route和RouteDefinition,也就是说他们是用来定位具体的Route和RouteDefinition的。


大军
847 声望183 粉丝

学而不思则罔,思而不学则殆


« 上一篇
nacos系列
下一篇 »
gateway - 启动