springcloud gateway简介

前言

Spring Cloud Gateway该项目提供了一个构建在 Spring 生态系统(包括 Spring 5Spring Boot 2 ,Project Reactor)之上的 API 网关,旨在提供一种简单而有效的方法来路由到 api,并为它们提供横切关注点,例如: 安全性、监视 / 度量和弹性扩容。官方原文链接

1. 引入

要在项目中包含 Spring Cloud Gateway,请使用具有 org.springframework.cloud 组 ID 和 spring-cloud-starter-gateway 项目 ID 的 starter,如果包含了 starter,但不希望启用 gateway,请设置 spring.cloud.gateway.enabled=false

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>

注意:
1.Spring Cloud Gateway需要Spring Boot和Spring Webflux提供的Netty环境运行,所以不能在传统的servlet容器(tomcat,jboss)中或者war包的方式运行。
2. Spring Cloud Gateway是基于Spring Boot 2.x, Spring WebFlux, Project Reactor的响应式编程的,因此部分spring框架它上面可能不能工作(Spring Security ,spring data的mysql等传统数据库(Nosql可以使用))。如果不熟悉这些项目,建议首先阅读它们的文档,以便在使用 Spring Cloud Gateway 之前熟悉一些新概念。

2. 词汇

  • Route:路由,网关的基本组件,它由一个 ID、一个目标 URI、一组Predicate和一组Filter组成。
  • Predicate:断言: 这是Java 8新特性。输入类型是 Spring Framework ServerWebExchange,以匹配来自 HTTP 请求的任何内容,比如headerparameter
  • Filter:过滤器。这些是 Spring Framework GatewayFilter 的实现,它们是用特定的工厂构建的。 这里,可以在发送下游请求之前或之后修改请求和响应。

3.工作流程

下面的图表概述了 Spring Cloud Gateway 的工作原理:
在这里插入图片描述
客户端向 Spring Cloud Gateway 网关发出请求。如果Gateway Handler Mapping确定请求与路由匹配,则将其发送到Gateway Web Handler。该Handler通过特定于请求的过滤器链来运行请求。用虚线划分过滤器的原因是,过滤器可以在发送代理请求之前和之后运行逻辑。所有的前置过滤器执行完毕后,发出代理请求,最后执行后置过滤器。

注意:如果routeurl没有声明端口号,则使用http或者https的默认端口号。

4.配置路由断言和过滤器

有两种配置断言和过滤器的方法: 简洁方式和完全扩展的参数。 下面的大多数例子都使用了简洁方式。

名称和参数名称将在每个部分的第一个或两个句子中作为代码列出。 参数通常按快捷配置所需的顺序列出。

4.1 简易配置

简易配置由固定的过滤器名称,后面跟着 = 和其他由,隔开的参数构成。

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

上面的示例使用两个参数定义了 Cookie 路由断言,这两个参数是 Cookie 名称(mycookie) 和与 mycookivalee 匹配的值。

4.2 完全展开的配置

完全展开的配置看起来更像带有名称 / 值对的标准 yaml 配置。 通常,会有一个 name 键和一个 args 键。 args 用于配置断言或过滤器的键值对。

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

上面两个例子分别展示了断言的简易配置和完全展开的配置。

 

5. 内置Predicates断言

5.1 After 路由断言

After 路由断言只有一个ZonedDateTime生成的datetime参数,只有在这个事件之后的请求才能匹配上。

Example 1. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

https://example.org这个地址在美国Denver时间2017-01-20 17:42:00之后才能

// 生成时间的代码
// demo 2020-05-06T19:16:43.338+08:00[Asia/Shanghai]
System.out.println(ZonedDateTime.now().toString());

5.2 Before 路由断言

Before 同样是一个时间断言,只不过是在配置的时间之前有效,过时之后失效。

Example 2. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

上面的链接地址在America/Denver时间2017-01-20 17:42::00之前有效

5.3 Between 路由断言

Between 路由断言,时间类断言,在声明的时间内有效。并且第二个时间必须大于第一个时间。

Example 3. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

上面的链接在America/Denver时间2017-01 20日17时42-21日17时47分之间有效。

5.4 Cookie 路由断言

Cookie 断言有两个参数,一个cookie 名称和一个java 正则表达式,这个断言匹配给定的cookie 名和值正则匹配的请求。

Example 4. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p

上面的匹配那些请求中包含参数名为chocolate并且值匹配ch.p的请求。

5.5 Header 路由断言

Header断言有两个参数,一个参数名,一个正则。只有当有这个参数并且值匹配正则的时候才能执行下去。

Example 5. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

这个路由规则匹配Header中包含X-Request-Id并且值为纯数字的请求。

5.6 Host 路由断言

Host 路由断言接受一个正则域名列表,正则是用英文句号分割的Ant-Style(ant 风格?)正则表达式。

Example 6. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

这个路由匹配somehost.org anotherhost.org这两个域名下的所有请求。

5.7 Method 路由断言

Method路由断言匹配一个或多个Http请求方式(GET POST PUT DELETE HEAD).

Example 7. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

这个路由匹配所有的GET POST请求。

5.8 Path 路径路由断言

Path路由断言接受两个参数:Spring PathMatcher 正则列表和一个名为 matchOptionalTrailingSeparator 的可选标志。

Example 8. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

如果请求路径为(例如: / red / 1或 / red / blue 或 / blue / green) ,则此路由匹配。
这个断言提取了URL中模板变量(像前面例子中声明的segment)组为key/value键值对放置在ServerWebExchange.getAttributes()中,并用已经声明的ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE来声明。这些内容可被GatewayFilter factories的一个名为get的方法很简单的去访问。

Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);

String segment = uriVariables.get("segment");

5.9 Query 查询路由断言

Query路由断言有两个参数: 一个必传参数 and 和一个可选的正则表达式。

Example 9. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=green

如果一个请求中包含green的参数,则匹配成功。

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=red, gree.

如果一个请求中包含参数red并且值匹配·gree.·这个正则,那么路由匹配。比如:green和greet。

5.10 RemoteAddr 远程地址路由断言

RemoteAddr路由断言接受一个来源地址的list,由IPv4或者IPv6组成,比如:192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)

Example 10. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

如果请求的远程地址是192.168.1.10,则此路由匹配。

5.11. Weight 权重路由断言

权重路由断言接受两个参数:group分组和Weight权重。权重是按组计算的。

Example 11. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

这条路线将80% 的流量转发到 weighthigh. org,20% 的流量转发到 weighlow. org。

6. GatewayFilter 过滤器

路由过滤器允许以某种方式修改传入 HTTP 请求或传出 HTTP 响应。路由过滤器的作用域是特定的路由。Spring Cloud Gateway 包括许多内置的网关过滤器工厂。有关如何使用以下过滤器的更详细示例,请参阅unit tests 单元测试

6.1 AddRequestHeader 过滤器

AddRequestHeader过滤器使用两个参数(name && value )

Example 13. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-red, blue

这个路由所有匹配请求的下游请求的头部中添加了 X-Request-red: blue。
AddRequestHeader通常用户匹配请求路径或者host中的变量。下面的例子中会将诸如 https://xxx.org/red/snzz 中的 snzz 放入 X-Request-red的value中。

Example 14. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - AddRequestHeader=X-Request-Red, Blue-{segment}

6.2. AddRequestParameter 添加参数过滤器

AddRequestParameter过滤器接受 name和 value参数

Example 15. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=red, blue

上面的例子中为所有请求的下游请求的查询字符串red=blue
通常用于为指定请求路径或者域名的请求中添加请求参数,下面的例子中。会为myhost.org域名下的所有请求加上一个参数,假如访问的是dev.myhost.org,那么请求中就会加上一个foo=bar-dev的参数。

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddRequestParameter=foo, bar-{segment}

6.3 Addresponseheader 过滤器

AddResponseHeader 采用 name和 value 参数:

Example 17. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        - AddResponseHeader=X-Response-Red, Blue

这将为所有匹配请求的下游响应头添加 X-Response-Red: Bar 头。
通常用于为指定请求路径或者域名的请求响应的消息头添加参数,下面的例子中。会为myhost.org域名下的所有请求响应体的头部加上一个参数,假如访问的是dev.myhost.org,那么响应头中就会加上一个foo=bar-dev的参数。

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddResponseHeader=foo, bar-{segment}

6.4 DedupeResponseHeader 去重响应过滤器

DedupeResponseHeader接受一个name参数和一个可选的strategy 参数。Name可以包含以空格分隔的header名称列表。

Example 19. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: https://example.org
        filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

在网关 CORS 逻辑和下游逻辑都添加了Access-Control-Allow-CredentialsAccess-Control-Allow-Origin响应头的情况下,这将删除重复的值。
DedupeResponseHeader过滤器还接受一个可选的策略参数。接受的值是 RETAIN_FIRST (默认值:保留第一个)、 RETAIN_FIRST (保留最后一个)和 RETAIN_UNIQUE(保留唯一的)。

6.5 Spring Cloud CircuitBreaker

Spring Cloud 断路器网关过滤器工厂使用 Spring Cloud 断路器 api 将网关路由包裹在断路器中。 支持多个可以与 Spring 云网关一起使用的库。 Spring Cloud 开箱即用地支持Resilience4J
要启用 Spring Cloud CircuitBreaker 过滤器,需要将 Spring-Cloud-starter-CircuitBreaker-reactor-resilience4j 放在类路径上。

Example 20. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: https://example.org
        filters:
        - CircuitBreaker=myCircuitBreaker

可以参考下面的API文档来配置这个断路器。Resilience4J Documentation

6.28 上面太多了,暂不一一说明,后续有时间了再补充

6.29 默认过滤器

你可以声明spring.cloud.gateway.default-filters来为所有的路由添加过滤器,这个属性是一个list。

Example 51. application.yml

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin

上面的配置会为httpbin请求路径下的请求的ResponseHeader中加入参数X-Response-Default-Red=Default-Blue

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值