1.Spring Cloud Gateway 是什么?

  它是一个基于 Spring Framework 的开源 API 网关服务。它旨在为微服务架构中的应用程序提供统一的路由和过滤器机制,以完成恳求的转发、降级、熔断、限流等功能。换言之,它便是网关(Gateway),充当了客户端和内部微服务之间的中介。

Spring Cloud Gateway 组成:

  1. 路由:界说恳求应该被转发到哪个方针地址。
  2. 断语:用于匹配恳求的条件,依据断语条件匹配到相应的路由。
  3. 过滤器:用于在恳求路由前或路由后进行一些处理、操作,比如增加头部信息、修改恳求体等。

Spring Cloud Gateway 根底运用(断语的运用)

   在微服务中,内部之间的通讯是用 OpenFeign + LoadBalancer 完成的。那前端向后端发送恳求的时候,我的拜访途径是什么呢?该向哪一个服务发送呢?该用什么来统筹外部与内部之间的通信呢?其实便是运用 Spring Cloud Gateway 来提供统一拜访地址或者界说一些规矩来处理恳求。

Spring Cloud Gateway 根底运用(断语的运用)

2. Gateway 的路由功能

2.1 准备工作

   创建两个模块,来完成 Gateway 的路由功能。gateway-service 为网关,user-service 为一个服务。

Spring Cloud Gateway 根底运用(断语的运用)

   在 gateway-servicepom. xml 中,增加依靠:

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

   在 user-servicepom. xml 中,增加依靠:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

   注意,Spring Cloud Gateway 不能配合 Spring Web(Spring MVC) 一起运用。也便是在同一个 pom 文件中不能同时存在。

   在 user-service 模块中随便写一个接口,然后装备 gateway 来完成路由的转发。

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getname")
    public String getName(){
        return "Name: 小明";
    }
}

2.2 装备路由

   现在装备 gateway

spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**
server:
  port: 8080

下面是 properties 格式的:

server.port=8080
spring.cloud.gateway.routes[0].id=userservice
spring.cloud.gateway.routes[0].uri=http://localhost:9090
spring.cloud.gateway.routes[0].predicates[0]=Path=/user/**
  • id: userservice,表明这个路由的仅有标识,不能重复,没有其他效果。
  • uri: http://localhost:9090,表明这个路由的方针地址。
  • predicates: 表明这个路由的断语列表,它有很多种类型,更多的类型后文介绍。
  • Path=/user/,表明这个断语的类型是 Path,用于匹配恳求途径,这里表明匹配以/user/开头的任意途径。

  这个路由规矩的意思是,假如恳求途径以/user/开头,就转发到http://localhost:9090这个地址。

   user-service 装备:

server:
  port: 9090

   发动程序后:

Spring Cloud Gateway 根底运用(断语的运用)

Spring Cloud Gateway 根底运用(断语的运用)

   能够看到,localhost: 8080/user/getname 能拜访到 9090 端口的 user-service 服务。这就完成了 localhost: 8080/user/getnamelocalhost: 9090/user/getname 途径的转化。

   假如一个模块中有多个路由需要转化,就能够运用英文逗号离隔:

spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**,/us/**,……
server:
  port: 8080

2.3 多个模块

   再增加一个模块 goods-service

Spring Cloud Gateway 根底运用(断语的运用)

@RestController
@RequestMapping("/goods")
public class GoodsController {
    @RequestMapping("/getname")
    public String getGoodsName(){
        return "红旗轿车";
    }
}
server:
  port: 7070

   因为新增加一个模块,那么就需要增加一个路由设置。gateway 的装备文件:

spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**
        - id: goodsservice
          uri: http://localhost:7070
          predicates:
            - Path=/goods/**
server:
  port: 8080

发动程序,并拜访 localhost: 8080/goods/getname

Spring Cloud Gateway 根底运用(断语的运用)

   能够看到 gateway 将不同的端口的服务整合到一起,这便是它的效果之一。

Spring Cloud Gateway 根底运用(断语的运用)

2.4 断语类型

  Gateway 的断语类型有:

  • After、Before、Between:依据恳求的时刻进行路由,能够指定一个时刻点或一个时刻区间。
  • Cookie:依据恳求中的cookie进行路由,能够指定cookie的称号和值的正则表达式。
  • Header:依据恳求头进行路由,能够指定恳求头的称号和值的正则表达式。
  • Host:依据恳求的主机名进行路由,能够指定一个或多个主机名,也能够运用通配符。
  • Method:依据恳求的方法进行路由,能够指定一个或多个HTTP方法,如GET、POST等。
  • Query:依据恳求的查询参数进行路由,能够指定参数的称号和值的正则表达式。
  • Path:匹配恳求途径。
  • Query:匹配恳求参数。
  • RemoteAdder:匹配恳求的 IP 地址。
  • Weight:依据权重来分发恳求。
  • XForwardedRemoteAddr:依据 HTTP 头 X-Forwarded-For 进行恳求过滤。

更详细的看官方文档: Spring Cloud Gateway

2.4.1 依据时刻匹配

   下面表明在 2024-01-28 T17:42:47.789 这个时刻之后才会匹配路由,+08:00[Asia/Shanghai] 为时区。

spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**
            - After=2024-01-28T17:42:47.789+08:00[Asia/Shanghai]

   在 2017-01-20 T17:42:47.789~2017-01-21 T17:42:47.789 之间的恳求能够被匹配。

spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**
	        - Between=2017-01-20T17:42:47.789+08:00[Asia/Shanghai], 2017-01-21T17:42:47.789+08:00[Asia/Shanghai]

2.4.2 Header 断语

spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**
        - id: goodsservice
          uri: http://localhost:7070
          predicates:
            - Path=/goods/**
            - Header=X-Request-Id, d+

  这个路由匹配条件是:假如恳求包含名为 X-Request-Id 的头,并且该头的值与正则表达式 d+ 匹配(即,它的值为一个或多个数字),则路由匹配。

(正则表达式的规矩:正则表达式 – 教程 | 菜鸟教程 (runoob.com)

没有 X-Request-Id 时 404:

Spring Cloud Gateway 根底运用(断语的运用)

增加 X-Request-Id 时,能拜访:

Spring Cloud Gateway 根底运用(断语的运用)

2.4.3 Method 断语

spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**
        - id: goodsservice
          uri: http://localhost:7070
          predicates:
            - Path=/goods/**
            - Method=GET,POST

   只能匹配 GET、POST 类型的恳求。

2.4.4 Weight 断语

spring:
  cloud:
    gateway:
      routes:
        - id: userservice1
          uri: http://localhost:9090
          predicates:
            - Weight=group1,10
        - id: userservice2
          uri: http://localhost:7070
          predicates:
            - Weight=group1,90

   假设 userservice1userservice2 模块都有“/user/getname”这个接口。上面的意思是:把大约 10% 的流量转发到 userservice1,而将大约 90% 的流量转发到 userservice2。要注意的是权重是按组核算的,上面的两个模块同归于 group1,那么就将这一组按份额来分流。

(最后,Gateway 必定需要结合 NacosLoadBalancer 来运用,这样才能发挥它的最大效果,本篇只介绍了 Gateway 的断语,其它(如过滤器)后续再更新……)