SpringCloud Gateway路由转发规则

简介: `Spring`在因`Netflix`开源流产事件后,在不断的更换`Netflix`相关的组件,比如:`Eureka`、`Zuul`、`Feign`、`Ribbon`等,`Zuul`的替代产品就是`SpringCloud Gateway`,这是`Spring`团队研发的网关组件,可以实现限流、安全认证、支持长连接等新特性。

Spring在因Netflix开源流产事件后,在不断的更换Netflix相关的组件,比如:EurekaZuulFeignRibbon等,Zuul的替代产品就是SpringCloud Gateway,这是Spring团队研发的网关组件,可以实现限流、安全认证、支持长连接等新特性。

Spring Cloud Gateway

Spring Cloud GatewaySpringCloud的全新子项目,该项目基于Spring5.xSpringBoot2.x技术版本进行编写,意在提供简单方便、可扩展的统一API路由管理方式。
概念解释:

  • Route(路由):路由是网关的基本单元,由ID、URI、一组Predicate、一组Filter组成,根据Predicate进行匹配转发。
  • Predicate(谓语、断言):路由转发的判断条件,目前SpringCloud Gateway支持多种方式,常见如:PathQueryMethodHeader等。
  • Filter(过滤器):过滤器是路由转发请求时所经过的过滤逻辑,可用于修改请求、响应内容。

Spring Cloud GateWay 工作流程如下所示
spring-cloud-gateway-work.png

客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。此处理程序运行时通过特定于请求的筛选链发送请求。过滤器被虚线分隔的原因是过滤器可以在发送代理请求之前或之后执行逻辑。执行所有“预”过滤逻辑,然后发出代理请求。在发出代理请求后,将执行“post”过滤器逻辑。

开始使用

Spring Cloud Gateway目前有两种方式进行配置:

  • application.yml配置文件方式
  • 通过@Bean注解RouteLocator方法返回值

在本章会侧重针对配置文件方式进行讲解,当然RouteLocator方式也会简单的告诉大家的使用方式。

添加依赖

添加Spring Cloud Gateway相关依赖,pom.xml如下所示:

//...省略部分内容
<properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <!--Spring Cloud Gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
//...省略部分内容

Spring Cloud Gateway Predicates

在我们开始本章内容之前我们要来先了解下Spring Cloud Gateway内部提供的所有谓语、断言,这样我们才能目标性的进行学习,我整理出来了一个脑图,如下所示:

SpringCloud-Gateway-Predicates.png

每一个Predicate的使用,你可以理解为:当满足这种条件后才会被转发,如果是多个,那就是都满足的情况下被转发。

Path 方式匹配转发

通过Path转发示例,我们讲解下上面的两种配置,分别是application.yml以及RouteLocator

配置文件匹配地址转发

我们在application.yml配置文件内添加对应的路由配置,如下所示:

spring:
  application:
    name: spring-cloud-gateway-sample
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            # 匹配路径转发
            - Path=/api-boot-datasource-switch.html
# 端口号
server:
  port: 9090

先来解释下route的组成部分:

  • id:路由的ID
  • uri:匹配路由的转发地址
  • predicates:配置该路由的断言,通过PredicateDefinition类进行接收配置。

在上面的配置中,当访问http://localhost:9090/api-boot-datasource-switch.html时就会被自动转发到https://blog.minbox.org/api-boot-datasource-switch.html,这里要注意完全匹配Path的值时才会进行路由转发。

访问效果如下所示:

spring-cloud-gateway-path-predicate.png

RouteLocator 匹配路径转发

在上面的配置中,如果使用RouteLocator方式该怎么进行配置呢?

如下所示:

@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
  return builder.routes()
    .route("blog", r -> 
           r.path("/api-boot-datasource-switch.html").uri("https://blog.minbox.org"))
    .build();
}

Before 方式匹配转发

当部署有访问时间限制的接口时,我们可以通过Before Predicate来完成某一个时间点之前允许访问,过时后则不允许转发请求到具体的服务,配置如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - Before=2019-05-01T00:00:00+08:00[Asia/Shanghai]

在上面配置中,我们允许2019-05-01日凌晨之前通过路由转发到https://blog.minbox.org,通过查看org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactory源码我们发现,Spring Cloud GatewayBefore断言采用的ZonedDateTime进行匹配时间,这里要注意存在时区的问题,需要配置[Asia/Shanghai]作为中国时区。

After 方式匹配转发

After PredicateBefore配置使用一致,匹配某一个时间点之后允许路由转发,如下所示配置:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - After=2019-04-29T00:00:00+08:00[Asia/Shanghai]

在上面配置中允许2019-04-29凌晨之后进行转发到https://blog.minbox.org

Between 方式匹配转发

那如果是一个时间段内允许请求转发,通过BeforeAfter组合配置也可以完成,不过Spring Cloud Gateway还是提供了Between方式,如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - Between=2019-04-29T00:00:00+08:00[Asia/Shanghai], 2019-05-01T00:00:00+08:00[Asia/Shanghai]

在上面配置中,允许在2019-04-29日凌晨后 & 2019-05-01凌晨之前请求转发到https://blog.minbox.org

Cookie 方式匹配转发

Spring Cloud Gateway 还提供了根据Cookie值的方式匹配转发请求,如果请求中所携带的Cookie值与配置的Predicate匹配,那么就可以被允许转发到指定地址,如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - Cookie=hengboy, yuqiyu

在上面配置中,如果客户端发送请求时携带了"hengboy=yuqiyu"的Cookie信息,则允许请求转发。

测试Cookie方式转发:

curl http://localhost:9090 --cookie "hengboy=yuqiyu"

通过上面方式我们是可以成功转发请求的,如果我们修改Cookie的值,就会导致无法转发,出现404。

Header 方式匹配转发

Spring Cloud Gateway可以根据发送请求的Header信息进行匹配转发,加入我们可以根据X-Request-Id的值进行匹配,如下所示:

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

在上面配置中,如果X-Request-Id的值为数字,那么就可以转发到https://blog.minbox.org,我们通过如下方式进行测试:

curl http://localhost:9090 -H "X-Request-Id:123456"

如果头信息为X-Request-Id:abc时,就会转发失败,出现404。

Host 方式匹配转发

Spring Cloud Gateway可以根据Host主机名进行匹配转发,如果我们的接口只允许**.yuqiyu.com域名进行访问,那么配置如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - Host=**.yuqiyu.com

测试如下所示:

 1. curl http://localhost:9090 -H "Host: yuqiyu.com"          // 匹配
 2. curl http://localhost:9090 -H "Host: api.yuqiyu.com"        // 匹配
 3. curl http://localhost:9090 -H "Host: admin.yuqiyu.com"  // 匹配
 4. curl http://localhost:9090 -H "Host: hengboy.com"          // 不匹配

请求方式 方式匹配转发

Rest请求风格的接口内往往会存在多种请求方式的接口,如果我们的接口只允许POST请求访问,那么配置如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - Method=POST

发送GET请求测试:

~ curl http://localhost:9090
{"timestamp":"2019-04-29T06:27:41.121+0000","path":"/","status":404,"error":"Not Found","message":null}

我们的请求并未被Spring Cloud Gateway进行转发,那么我们再来通过POST请求进行测试:

curl -X POST http://localhost:9090

是可以被转发到目标地址uri的,不过我的这个博客是OSS部署的,阿里云限制了POST访问,尽管如此我们也证明了可以转发。

请求参数 方式匹配转发

Spring Cloud GateWay还支持根据指定的参数进行匹配,Query方式的Predicate也有两种方式匹配情况,如下所示:

  • 请求中存在xxx参数

    spring:
      cloud:
        gateway:
          routes:
            - id: blog
              uri: https://blog.minbox.org
              predicates:
                - Query=xxx

    我们通过curl http://localhost:9090\?xxx\=123是可以被成功转发的,只要参数存在xxx就会被成功转发,否则出现404转发失败。

  • 请求中存在xxx参数且值为zzz

    spring:
      cloud:
        gateway:
          routes:
            - id: blog
              uri: https://blog.minbox.org
              predicates:
                - Query=xxx, zzz

    根据上面配置,我们限定了参数xxx必须为zzz时才会被成功转发,否则同样会出现404抓发失败。

请求路径 方式匹配转发

Spring Cloud Gateway提供了请求路径变量方式匹配转发,如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - Path=/article/{articleId}

在上面配置中{articleId}是一个路径变量,可以是任意值,匹配/article/1/article/abc等,测试如下所示:

~ curl http://localhost:9090/article/1            // 匹配
~ curl http://localhost:9090/article/abc        // 匹配
~ curl http://localhost:9090/article/1/1        // 不匹配

请求IP 方式匹配转发

Spring Cloud Gateway可以限制允许访问接口的客户端IP地址,配置后只对指定IP地址的客户端进行请求转发,配置如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - RemoteAddr=192.168.1.56/24

在上面我们配置了192.168.1.56/24,其中192.168.1.56是客户端的IP地址,而24则是子网掩码。

组合示例

相同的Predicate也可以配置多个,请求的转发是必须满足所有的Predicate后才可以进行路由转发,组合使用示例如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: blog
          uri: https://blog.minbox.org
          predicates:
            - Query=author, hengboy
            - Query=yuqiyu
            - Method=GET
            - Cookie=hengboy, yuqiyu
            - Header=X-Request-Id, \d+
            - RemoteAddr=192.168.1.56/24

总结

本章节讲解了Spring Cloud Gateway的相关谓词、断言基本使用方式,GateWay内部提供了很多种灵活的路由转发规则,在同一个路由内存在多个Predicate时,同时满足规则后请求才会被路由转发。

相关文章
|
17天前
|
JSON Java API
利用Spring Cloud Gateway Predicate优化微服务路由策略
Spring Cloud Gateway 的路由配置中,`predicates`​(断言)用于定义哪些请求应该匹配特定的路由规则。 断言是Gateway在进行路由时,根据具体的请求信息如请求路径、请求方法、请求参数等进行匹配的规则。当一个请求的信息符合断言设置的条件时,Gateway就会将该请求路由到对应的服务上。
120 69
利用Spring Cloud Gateway Predicate优化微服务路由策略
|
1月前
|
JavaScript Java Kotlin
深入 Spring Cloud Gateway 过滤器
Spring Cloud Gateway 是新一代微服务网关框架,支持多种过滤器实现。本文详解了 `GlobalFilter`、`GatewayFilter` 和 `AbstractGatewayFilterFactory` 三种过滤器的实现方式及其应用场景,帮助开发者高效利用这些工具进行网关开发。
213 1
|
2月前
|
负载均衡 Java API
项目中用的网关Gateway及SpringCloud
Spring Cloud Gateway 是一个功能强大、灵活易用的API网关解决方案。通过配置路由、过滤器、熔断器和限流等功能,可以有效地管理和保护微服务。本文详细介绍了Spring Cloud Gateway的基本概念、配置方法和实际应用,希望能帮助开发者更好地理解和使用这一工具。通过合理使用Spring Cloud Gateway,可以显著提升微服务架构的健壮性和可维护性。
62 0
|
4月前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
4月前
|
Java 开发者 Spring
Spring Cloud Gateway 中,过滤器的分类有哪些?
Spring Cloud Gateway 中,过滤器的分类有哪些?
99 3
|
4月前
|
负载均衡 Java 网络架构
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
207 5
|
3月前
|
负载均衡 Java API
【Spring Cloud生态】Spring Cloud Gateway基本配置
【Spring Cloud生态】Spring Cloud Gateway基本配置
69 0
|
4月前
|
SpringCloudAlibaba API 开发者
新版-SpringCloud+SpringCloud Alibaba
新版-SpringCloud+SpringCloud Alibaba
|
17天前
|
SpringCloudAlibaba 负载均衡 Dubbo
【SpringCloud Alibaba系列】Dubbo高级特性篇
本章我们介绍Dubbo的常用高级特性,包括序列化、地址缓存、超时与重试机制、多版本、负载均衡。集群容错、服务降级等。
【SpringCloud Alibaba系列】Dubbo高级特性篇
|
17天前
|
存储 SpringCloudAlibaba Java
【SpringCloud Alibaba系列】一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论
一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论。
【SpringCloud Alibaba系列】一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论