gateway - 流程及组件

2021年01月14日 阅读数:5
这篇文章主要向大家介绍gateway - 流程及组件,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

流程

咱们用官方的图片来讲明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.pngjava

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同样的方法了。spring

RouteDefinition

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

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是同样的。app

Locator

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