Spring Cloud Gateway 基础使用(断言的使用)

1.Spring Cloud Gateway 是什么?

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

Spring Cloud Gateway 组成:

  1. 路由:定义请求应该被转发到哪个目标地址。
  2. 断言:用于匹配请求的条件,根据断言条件匹配到相应的路由。
  3. 过滤器:用于在请求路由前或路由后进行一些处理、操作,比如添加头部信息、修改请求体等。

   在微服务中,内部之间的通讯是用 OpenFeign + LoadBalancer 实现的。那前端向后端发送请求的时候,我的访问路径是什么呢?该向哪一个服务发送呢?该用什么来统筹外部与内部之间的通信呢?其实就是使用 Spring Cloud Gateway 来提供统一访问地址或者定义一些规则来处理请求。

2. Gateway 的路由功能

2.1 准备工作

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

   在 gateway-servicepom. xml 中,添加依赖:

xml 复制代码
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

   在 user-servicepom. xml 中,添加依赖:

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 来实现路由的转发。

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

2.2 配置路由

   现在配置 gateway

yml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**

server:
  port: 8080

下面是 properties 格式的:

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 配置:

yml 复制代码
server:
  port: 9090

   启动程序后:

   可以看到,localhost: 8080/user/getname 能访问到 9090 端口的 user-service 服务。这就实现了 localhost: 8080/user/getnamelocalhost: 9090/user/getname 路径的转换。

   如果一个模块中有多个路由需要转换,就可以使用英文逗号隔开:

yml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: http://localhost:9090
          predicates:
            - Path=/user/**,/us/**,......
server:
  port: 8080

2.3 多个模块

   再添加一个模块 goods-service

java 复制代码
@RestController
@RequestMapping("/goods")
public class GoodsController {

    @RequestMapping("/getname")
    public String getGoodsName(){
        return "红旗汽车";
    }
}
yml 复制代码
server:
  port: 7070

   由于新增加一个模块,那么就需要添加一个路由设置。gateway 的配置文件:

yml 复制代码
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

   可以看到 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] 为时区。

yml 复制代码
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 之间的请求可以被匹配。

yml 复制代码
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 断言

yml 复制代码
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:

添加 X-Request-Id 时,能访问:

2.4.3 Method 断言

yml 复制代码
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 断言

yml 复制代码
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 的断言,其它(如过滤器)后续再更新......)

相关推荐
码云数智-园园16 分钟前
C++20 Modules 模块详解
java·开发语言·spring
程序员黑豆19 分钟前
JDK 下载安装与配置详细教程
java·前端·ai编程
小宇宙Zz1 小时前
Maven依赖冲突
java·服务器·maven
swordbob1 小时前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
咖啡八杯1 小时前
GoF设计模式——享元模式
java·spring·设计模式·享元模式
十五喵源码网1 小时前
基于springboot2+vue2的租房管理系统
java·毕业设计·springboot·论文笔记
摇滚侠1 小时前
IDEA 创建 Java 项目 手动整合 SSM 框架
java·ide·intellij-idea
源分享1 小时前
Java线程同步的多种实现方法(非常详细)
java·开发语言·jvm
Flittly1 小时前
【AgentScope Java新手村系列】(10)实战-多Agent天气助手
java·spring boot·spring
李少兄2 小时前
从原理到实战:Spring IoC/DI 核心知识体系与高频面试题全解
java·后端·spring