流程
咱们用官网的图片来阐明 gateway 的流程。当客户端拜访 gateway 的时候,首先会通过 DispatcherHandler#handle 调用 RoutePredicateHandlerMapping,也就是图中的 Gateway Handler Mapping,而后再调用 FilteringWebHandler,也就是图中的 Gateway Web Handler。
咱们从 java8 系列晓得,java8 的 Predicate 函数,用来示意一个波及类型 T 的布尔表达式,RoutePredicateHandlerMapping 也是相似的,当返回 false 的时候,阐明不符合要求,所以他次要是用来判断路由是否匹配,不匹配就返回 false。
FilteringWebHandler 从名字上看就晓得是用来解决过滤器的,从图上能够看出,他会有一个 filter 链,用来解决申请前和申请后的操作,相似 zuul 的 pre 和 post。
Route
下面咱们曾经晓得了 gateway 的流程,这个时候假如咱们有多个 URL,比方 example.com/testA 和 example.com/testB 过去,咱们怎么晓得哪些申请能够哪些申请不能够呢?咱们能够用一个大的 map 来存储这些 URL,然而咱们如何针对某个 URL 进行特定的过滤申请呢,所以这样粗粒度管制是不行的。所以 gateway 是这样设计的:他为每个 URL 都配置了相应的规定和路由。如下图所示,每个路由 Route 都有本人的 id,url,predicate 以及 gatewayFilters。
咱们看到 gatewayFilters 是 s 结尾的,就猜到了他是汇合,那 predicate 没有 s,阐明他只能带一个 Predicate 吗,其实不是的,java8 的 Predicate 有 or、and、negate 的办法,他也是有的,所以他是这样设计的,当咱们只有一个 Predicate 的时候:
当调用 and 办法,这样就有了两个 Predicate,他的构造如下,他会把已有的 Predicate 放入 left,再把新增的 Predicate 放入 right。
当再调用 and 办法的时候,这个时候就有了 3 个 Predicate,他的构造如下:
当然调用 or 也是相似的,他通过这样的构造,就能够实现和 java8 的 Predicate 一样的办法了。
RouteDefinition
下面曾经晓得了 Route 的构造,然而咱们却不能间接在 application.yml 文件里配置,起因就是 Predicate 的简单的构造,所以咱们通过 RouteDefinition 来简化配置,RouteDefinition 的构造如下:
能够看到,和 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 的。