版本:2.0.2.RELEASE
链接:http://spring.io/projects/spring-cloud-gateway#overview
本章主要目录如下
Spring Cloud Gateway是什么?
Spring Cloud Gateway特征有什么?
Spring Cloud Gateway应如何引入?
Spring Cloud Gateway词汇表有什么?
Spring Cloud Gateway如何工作?
Spring Cloud Gateway谓词是什么?
本章主要内容如下
1.Spring Cloud Gateway是什么
该项目提供了一个用于在Spring MVC之上构建API网关的库。Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到API,并为他们提供横切关注点,例如:安全性,监控/指标和弹性。
2.Spring Cloud Gateway特征有什么
基于Spring Framework 5,Project Reactor和Spring Boot 2.0构建
能够匹配任何请求属性上的路由。
谓词和过滤器对于路由是特定的。
Hystrix断路器集成。
Spring Cloud DiscoveryClient集成
易于编写谓词和过滤器
请求率限制
路径重写
3.Spring Cloud Gateway应如何引入
要在项目中引入 Spring Cloud Gateway,请使用 org.springframework.cloud 启动依赖包,其构件id是spring-cloud-starter-gateway。请参阅Spring Cloud Project页面,以获取有关使用当前 Spring Cloud Release Train 设置构建系统的详细信息。如果引入启动依赖包,但由于某种原因,您不希望启用网关,请设置 spring.cloud.gateway.enabled =false。
Spring Cloud Gateway 需要 Spring Boot 和 Spring Webflux 提供 Netty 运行时。它不能在传统的 Servlet 容器中工作或构建为 WAR。
4.Spring Cloud Gateway词汇表有什么?
路由:路由是网关的基本构建模块。它由一个 ID,一个目标 URI,一组谓词和一个过滤器的集合定义。如果聚合谓词为真,则路由匹配。
谓词:这是一个 Java 8 函数谓词。输入类型是一个 Spring 框架的 ServerWebExchange。这允许开发人员匹配来自 HTTP 请求的任何内容,例如头部或参数。
过滤器:这些是 Spring 框架网关过滤器在特定工厂中构建的实例。这里,可以在发送下游请求之前或之后修改请求和响应。
5.Spring Cloud Gateway如何工作?
客户端向 Spring Cloud Gateway 发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关 Web 处理程序。这个运行的处理程序通过特定于请求的过滤器链发送请求。过滤器被虚线划分的原因是过滤器可以在发送代理请求之前或之后执行逻辑。执行所有“pre”过滤器逻辑,然后进行代理请求。在发出代理请求之后,执行“post”过滤器逻辑。
注意:在没有端口的路由中定义的URI将分别为HTTP和HTTPS URI获取默认端口设置为80和443。
6.Spring Cloud Gateway谓词是什么?
Spring Cloud Gateway 将路由作为 Spring WebFlux HandlerMapping 基础结构的一部分进行匹配。Spring Cloud Gateway 包含许多内置的路由谓词工厂。所有这些谓词都匹配 HTTP 请求的不同属性。多个谓词工厂可以通过逻辑与进行组合。
After 路由谓词工厂
After 路由谓词工厂采用一个 datetime 类型的参数。此谓词匹配当前日期时间之后发生的请求。
application.yml
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
此路由与 2017 年 1 月 20 日 17:42 MountainTime(Denver)之后的所有请求相匹配。
Before 路由谓词工厂
Before 路由谓词工厂采用一个 datetime 类型的参数。此谓词匹配当前日期时间之前发生的请求。
application.yml
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
此路由与 2017 年 1 月 20 日 17:42 MountainTime(Denver)之后的所有请求相匹配。
Between 路由谓词工厂
Between 路由谓词工厂采用两个参数,datetime1 和datetime2。此谓词匹配datetime1 之后和 datetime2 之前发生的请求。datetime2 参数必须在 datetime1 之后。
application.yml
spring:
cloud:
gateway:
routes:
- id: between_route
uri: http://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
此路由与 2017 年 1 月 20 日 17:42 Mountain Time (Denver)之后和 2017 年 1 月 21 日17:42 Mountain Time (Denver)之前的所有请求相匹配,这对维护窗口很有用。
Cookie 路由谓词工厂
Cookie 路由谓词工厂采用两个参数,cookie 名称和正则表达式。此谓词匹配具有给定名称的 cookie,值与正则表达式匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://example.org
predicates:
- Cookie=chocolate, ch.p
此路由与请求匹配的 cookie 名称为 chocolate,其值与 CH.P 正则表达式匹配。
Header 路由谓词工厂
Header 路由谓词工厂采用两个参数,Header 名称和正则表达式。此谓词与具有给定名称且值与正则表达式匹配的 Header 匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.org
predicates:
- Header=X-Request-Id, \d+
如果请求具有名为 X-Request-Id 的 Header,其值与\d+正则表达式匹配(具有一个或多个数字的值),则该路由匹配。
Host 路由谓词工厂
Host 路由谓词工厂采用一个参数:主机名模式。该模式是一种 Ant 样式模式作为分隔符。此谓词与匹配该模式的主机头部匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Host=**.somehost.org
如果请求的主机头部具有值www.somehost.org或beta.somehost.org,则此路由将匹配。
Method 路由谓词工厂
Method 路由谓词工厂采用一个参数:要匹配的 HTTP 方法。
application.yml
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://example.org
predicates:
- Method=GET
如果请求方法是 GET,则此路由将匹配。
Path 路由谓词工厂
Path 路由谓词工厂采用一个参数:Spring PurthMatter 模式。
application.yml
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Path=/foo/{segment}
如果请求路径如:/foo/1 或/foo/bar,则此路由将匹配。
此谓词提取 URI 模板变量(如上面示例中定义的 segment)作为名称和值的映射,并将其放置在 ServerWebExchange.getAttributes()中,其中键定义在
PathRoutePre.e.URL_PREDICATE_VARS_ATTR 中。这些值随后可供网关过滤器工厂使用。
Query 路由谓词工厂
Query 路由谓词工厂采用两个参数:一个必需的参数和一个可选的正则表达式。
application.yml
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=baz
如果请求包含 baz 查询参数,此路由将匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=foo, ba.
如果请求包含一个 foo 查询参数,它的值与 ba.正则表达式匹配,则此路由将匹配,所以bar 和 baz 都将匹配。
RemoteAddr 路由谓词工厂
RemoteAddr 路由谓词工厂采用 CIDR 符号(IPv4 或 IPv6)字符串的列表(最小值为1),例如 192.168.0.1/16(其中 192.168.0.1 是 IP 地址,16 是子网掩码)。
application.yml
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://example.org
predicates:
- RemoteAddr=192.168.1.1/24
如果请求的远程地址为192.1681.10,则该路由将匹配。
修改远程地址的解析方式
默认情况下,RemoteAddr 路由谓词工厂使用传入请求中的远程地址。如果 Spring Cloud Gateway 位于代理层后面,则可能与实际客户端 IP 地址不匹配。可以通过设置自定义RemoteAddressResolver来自定义解析远程地址的方式。Spring Cloud Gateway 附带一个非默认远程地址解析器,它基于 X-Forwarded-For 头部和XForwardedRemoteAddressResolver。
XForwardedRemoteAddressResolver 有两种静态构造函数方法,它们采用不同的安全方法:
XForwardedRemoteAddressResolver::trustAll 返回一个 RemoteAddressResolver,它总是使用在 X-Forwared-For 报头中找到的第一个 IP 地址。这种方法容易受到欺骗,因为恶意客户端可以为解析器接收的 X-Forwared-For 设置初始值。
XForwardedRemoteAddressResolver :: maxTrustedIndex 采用与 Spring Cloud Gateway 前面运行的可信基础设施数量相关的索引。例如,如果只能通过 HAProxy 访问 Spring Cloud Gateway,则应使用值 1。如果在访问 Spring Cloud Gateway 之前需要两跳可信基础设施,那么应该使用值 2。
给出以下头部值:
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
下面的 maxTrustedIndex 值将产生以下远程地址。
使用 Java 配置:
GatewayConfig.java
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
.maxTrustedIndex(1);
...
.route("direct-route",
r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
.uri("https://downstream1")
.route("proxied-route",
r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
.uri("https://downstream2")
)
关注米兜Java,下一章将一起讨论网关过滤器工厂。