Spring Cloud之Gateway(一):基本了解及谓词详解

版权声明:本文为博主原创文章,可自由转载、引用,但需注明文章出处。 https://blog.csdn.net/StarskyBoy/article/details/84900266

版本: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,下一章将一起讨论网关过滤器工厂。

猜你喜欢

转载自blog.csdn.net/StarskyBoy/article/details/84900266