Spring Cloud Gateway 的简单介绍和基本使用
前言
本文主要对Spring Cloud Gateway进行简单的概念介绍,并通过多模块编程的方式进行一个简单的实操。
文章目录
- 前言
- 1 什么是网关(概念)
- 2 微服务中的网关
- 2.1 问题1
- 2.2 问题2
- 3 网关作用
- 4 Spring Cloud Gateway组成
- 5 Spring Cloud Gateway基础使用
- 5.1 父类pom.xml依赖
- 5.2子模块Userservice
- 5.3 子模块GatewayService
- 5.4 实操1
- 5.5 实操2
- 5.6 注意事项
- 6 断言类型
1 什么是网关(概念)
网关是一种网络设备,它用于连接不同网络之间的数据传输。它是在网络层级上工作的,能够将数据从一个网络传输到另一个网络。网关可以是物理设备,如路由器,也可以是软件程序,如网络服务器。
2 微服务中的网关
在微服务架构中,网关的作用主要是用来作为客户端到内部服务端之间中间转发人,因为在微服务架构中,后端服务基本上会被放在私网中,不对外开放地址的,那么客户端身在远方不跟后端服务在一个私网中,是无法通过具体地址访问到后端服务的。
那么这个时候,就需要一个中间人作为连接二者的点,而这个中间人,在私网中,唯独他的IP对外开放,服务器多的情况下,这个中间人还需要额外做一份请求分发的工作,这个中间人我们专业一点就叫做:网关
2.1 问题1
问:这个时候可能会有朋友会问:客户端和服务端沟通不是可以通过OpenFeign+LoadBalancer吗????
答:现在的项目前后端分离项目比较多,我们后端是Java,OpenFeign+LoadBalancer的使用需要Jar包,但是我们前端(Vue、三剑客)语言并不能适配Jar包,所以就需要第三个人作为中间人,衔接前端客户端和后端服务端,而OpenFeign+LoadBalancer则作为后端中的通信使用,或者你可以理解访问过程为:前端客户端->网关->后端客户端->后端服务端

2.2 问题2
问:为什么不用Nginx这种反向代理作为中间人?
答:在微服务架构中,你要部署很多个后端且独立存在,这就意味着我前脚在这台服务器上刚登录认证过,后脚我的请求到另一台服务器就被认为是未认证请求,这不就成了我的每一次请求都被提示未登录认证。而我们的网关可以统一认证处理,就实现一次登录,各服务端生效的效果,当然还不止这些效果,接下来便会逐一介绍。
3 网关作用
- 路由功能:网关可以根据目标地址不同,选择最佳路径将请求从源地址发送到目标地址。
- 安全控制(统一鉴权):网关可以设置安全策略,对数据包进行检查和过滤,可以验证和授权网络数据包,并阻止未授权数据包访问。(防火墙是一种常用的网关设备,用于保护和过滤网络免收恶意攻击和未经授权的访问)
- 协议转换:不同网络使用不同的通信协议,网关可以进行协议转换,使不同设备之间可以互相访问(例如:HTTP->HTTPS)
- 网络地址转换(NAT):网络地址转换,将内部私有IP地址转换为外部网络公共IP地址。
总而言之,网关是一个关键的网络设备,它起到连接不同网络之间的桥梁作用,使得数据能够在不同网络之间传输和交换。
4 Spring Cloud Gateway组成
- 路由(route):定义了请求应该被发往到哪个的服务端的目标地址,路由由路由ID、断言、目标URI、过滤器组成。通过配置多个路由器,可以实现不同请求的路由规则。
- 断言(Predicate):用于匹配请求的条件,请求匹配断言条件,则会被路由到对应的目标地址。断言可以基于请求的路径、请求头、请求参数等信息进行匹配。
- 过滤器(Filter):用于路由请求前后统一处理,如添加请求头、修改请求体等。
5 Spring Cloud Gateway基础使用
下面我们通过多模块编程的方式演示Spring Cloud Gateway的使用,跳过创建过程,直接展示结果:

5.1 父类pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>Spring-Cloud-Gateway-Demo</artifactId><version>0.0.1-SNAPSHOT</version><name>Spring-Cloud-Gateway-Demo</name><description>Spring-Cloud-Gateway-Demo</description><packaging>pom</packaging><modules><module>UserService</module><module>GatewayService</module></modules><properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>3.0.2</spring-boot.version><spring-cloud.version>2022.0.0</spring-cloud.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</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.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>17</source><target>17</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
</project>
5.2子模块Userservice
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>UserService</artifactId><version>0.0.1-SNAPSHOT</version><name>UserService</name><description>UserService</description><parent><groupId>com.example</groupId><artifactId>Spring-Cloud-Gateway-Demo</artifactId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>17</source><target>17</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.example.userservice.UserServiceApplication</mainClass><skip>true</skip></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
</project>
application.yml
server:port: 10086
controller代码
@RestController
@RequestMapping("/user")
public class UserControler {@RequestMapping("/getrandom")public String getRandom(){return "userservice:10086-"+new Random().nextInt(1000);}
}
5.3 子模块GatewayService
Spring Cloud Gateway分为两个步骤:
- 导入Gateway依赖(pom文件)
- 设置网关规则(yml文件)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>GatewayService</artifactId><version>0.0.1-SNAPSHOT</version><name>GatewayService</name><description>GatewayService</description><parent><groupId>com.example</groupId><artifactId>Spring-Cloud-Gateway-Demo</artifactId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></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><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>17</source><target>17</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.example.gatewayservice.GatewayServiceApplication</mainClass><skip>true</skip></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories></project>
application.yml
server:port: 8080spring:cloud:gateway:routes:- id: userservice #服务IDuri: http://localhost:10086 #目的地址路由predicates: #断言- Path=/user/** #断言匹配规则
5.4 实操1
启动UserService和启动GatewayService

我们先正常访问UserService中的路由(http://localhost:10086/user/getrandom)
结果:

现在已经确认UserService是正常的,那么我们接下来就看看通过网关(http://localhost:8080/user/getrandom)能不能访问到它:

从中可以发现,我们的Gateway可以帮我们去完成请求转发到适合的服务端上。
5.5 实操2
如果是对于多组的路由该如何编写GatewayService的application.yml呢?编写时又该注意什么?
以下面为例进行说明:

server:port: 8080spring:cloud:gateway:routes:- id: userserviceuri: http://localhost:10086 #路由predicates:- Path=/user/**, /update/**- id: adminserviceuri: http://localhost:9000predicates:- Path=/admin/**
照虎画猫,我们在创建adminservice子模块与/update/xxx服务
UpdateController类

@RestController
@RequestMapping("/update")
public class UpdateController {@RequestMapping("/op")public String updateOrInsert(){return "updateOrInsert";}
}
AdminService.AdminController

@RestController
@RequestMapping("/admin")
public class AdminController {@RequestMapping("/getroles")public String getRoles(){return "AdminService:9000-admin";}
}
下面就进行访问测试,网关能否正确应对多个请求的分发
http://localhost:8080/update/op (√)

http://localhost:8080/admin/getroles(√)

补充:
上面我们介绍了application.yml文件中对于数组的写法,而对于application.propeties编写方式如下server.port=9000 spring.cloud.gateway.routes[0].id=userservice spring.cloud.gateway.routes[0].uri=http://localhost:10086 spring.cloud.gateway.routes[0].predicates[0]=Path=/user/** spring.cloud.gateway.routes[0].predicates[1]=Path=/update/** spring.cloud.gateway.routes[1].id=adminservice spring.cloud.gateway.routes[1].uri=http://localhost:9000 spring.cloud.gateway.routes[1].predicates[0]=Path=/admin/**
5.6 注意事项
细心的朋友可能已经发现了,在多模块项目中,我的SpringWeb依赖没有放到父模块pom中,而是放在子模块。
这是因为父类中添加SpringWeb依赖会导致全子类都使用,而我们的Spring Cloud Gateway是基于Reactive进行开发的,不能使用简单的Spring Web依赖,需要使用Spring Reactive Web依赖,但是Spring Cloud Gateway底层中已经包含了这个依赖,所以我们没有在GatewayService中导入Spring Reactive Web,在其他子模块中导入Spring web依赖的原因。

假如我们错误的将Spring Web适用到Spring Cloud Gateway模块中,也会有error抛出,示例如下:

错误中也告诉我们解决方式,要么在gateway中使用Spring Reactive Web要么吧Spring Web移除
6 断言类型
Spring Cloud Gateway支持的断言类型目前有12种,包含以下这些:
- 根据时间匹配(包含3中类型)
a. After:请求在指定时间之后才匹配
b. Before: 请求在指定时间之前才匹配
c. Between: 请求在指定时间中才匹配 - cookie:配置请求中的Cookie值
- Header:配置请求中的Header值
- Host:匹配请求头中的Host值
- Method:匹配请求头中的Method的值
- Path: 匹配请求路径
- Query: 匹配请求参数
- RemoteAddr:匹配请求的IP地址,支持IPV4和IPV6
- Weight:根据权重来分发请求,权重根据Group来计算
10.XForwardRemoteAddr:根据X-ForWord-For匹配
官方参考文档:
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
其中Cookie和Header方式的匹配需要配合正则表达式来使用
正则表达式
\w+:匹配一个或多个字母、数字、下划线字符\s+:匹配一个或多个空白字符 (包括空格、制表符、换行符等)。.*:匹配任意字符(除了换行符) 零次或多次.+:匹配除了换行符之外的任意字符一次或多次。[abc]:匹配字符集中的任意一个字符,例如 [abc] 可以匹配a、b或c。[^abc]:匹配除了字符集中的任意字符之外的任意字符,例如[^abc] 可以匹配除了a、b和c之外的任意字符^:匹配字符串的开始位置$:匹配字符串的结束位置
9.|:表示"或”的意思,用于匹配多个模式中的任意一个10.(): 用10.():于分组,可以将一组字符作为一个整体进行匹配。
相关文章:
Spring Cloud Gateway 的简单介绍和基本使用
前言 本文主要对Spring Cloud Gateway进行简单的概念介绍,并通过多模块编程的方式进行一个简单的实操。 文章目录 前言1 什么是网关(概念)2 微服务中的网关2.1 问题12.2 问题2 3 网关作用4 Spring Cloud Gateway组成5 Spring Cloud Gateway基…...
Leaflet结合Echarts实现迁徙图
效果图如下: <!DOCTYPE html> <html><head><title>Leaflet结合Echarts4实现迁徙图</title><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0">…...
在mysql存储过程中间部分,使用游标遍历动态结果集(游标动态传参使用)
mysql游标动态传参实现(动态游标) 1.问题2.需求描述3.实现3.1.使用3.2.代码(直接看这都可以) 1.问题 众所周知,mysql存储过程功能是没有oracle的包功能强大的,但是在去O的趋势下,mysql存储过程的…...
全球SAR卫星大盘点与回波数据处理专栏目录
近年来,随着商业航天的蓬勃发展,商业SAR卫星星座成为美欧等主要航天国家的发展重点,目前已在全球范围内涌现出众多初创公司进军商业SAR领域,开始构建大规模商业微小SAR卫星星座,其所具有的创新服务能力将为传统的商业遥…...
C语言重点编程题——21-30
目录 21. 从键盘输入的10个整数中,找出第一个能被7整除的数。若找到,打印此数后退出循环;若未找到,打印"not exist" ★★★★22.有一个一维数组,内放10个学生成绩,写一个函数,求出平均分。 23.有N个学生,每个学生的信息包括学号、 性别、姓名、四门课的成绩…...
pip install 使用清华镜像源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package 官方文档: pypi | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror...
VBA技术资料MF86:将PPT文件批量另存为PDF文件
我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套,分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的入门,到…...
taro h5 ios解决input不能自动获取焦点拉起键盘
描述:页面中有个按钮,点击跳转到第二个页面(有input),能直接获取焦点拉起键盘输入 安卓: 直接用focus() ios: focus无效,必须手动拉起 原理: 点击按钮的时候拉起一…...
「Docker」如何在苹果电脑上构建简单的Go云原生程序「MacOS」
介绍 使用Docker开发Golang云原生应用程序,使用Golang服务和Redis服务 注:写得很详细 为方便我的朋友可以看懂 环境部署 确保已经安装Go、docker等基础配置 官网下载链接直达:Docker官网下载 Go官网下载 操作步骤 第一步 创建一个…...
Vue环境的搭建
1.Vue开发的两种方式 (1)核心包传统开发模式 基于html/css/js文件,直接引入,开发Vue。 (2)工程化开发模式(更常用的一种): 主要是基于构建工具(例如,webp…...
在Spring Boot中实现单文件,多文件上传
这篇文章算是一篇水文,因为也没啥好讲的,在Spring Boot中,上传文件是我们常常做的,包括我们在实际开发过程中,我们也经常碰到与文件上传有关的功能,这也算是我们常用的一个功能了,毕竟作为开发者…...
如何在 Web 应用程序中查找端点?
如何在 Web 应用程序中查找端点? 这篇文章主要讲述了如何在网络应用中找到端点。以下是文章的主要要点: 端点是网络服务的访问地址,通过引用这个URL,客户可以访问服务提供的操作。端点提供了寻址Web服务端点所需的信息。 HTTP消息是服务器和客户端之间交换数据的方式,包…...
使用el-scrollbar实现定位滚动,以及el-scrollbar去掉横向滚动条
实现滚动 <el-scrollbar ref"scroll" style"height: 100%;">// ... </el-scrollbar>可以使用如下属性: 想要滚动到哪个指定位置,自己获取或计算 this.$refs[scroll].wrap.scrollTop 0 //想滚到哪个高度,…...
AOP + 自定义注解实现日志打印
1. 先定义个注解,让它作用于方法上 Target({ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) public interface Loggable {}2. 定义切面 Aspect Component Slf4j public class LogMethodCallAspect {Pointcut("annotation(com.wy.spring_demo.aop.…...
美团YOLOv6量化部署实战方案
文章目录 1. 背景和难点2. 量化方案实战2.1 重参数化优化器2.1.1 RepOpt2.1.2 RepOpt 版本的 PTQ2.1.3 RepOpt 版本的 QAT2.2 基于量化敏感度分析的部分量化2.3 基于通道蒸馏的量化感知训练2.3.1 通道蒸馏2.3.2 YOLOv6 量化感知蒸馏框架3. 部署时优化3.1 图优化3.1.1 性能分析3…...
hive杂谈
数据仓库是一个面向主题的、集成的、非易失的、随时间变化的,用来支持管理人员决策的数据集合,数据仓库中包含了粒度化的企业数据。 数据仓库的主要特征是:主题性、集成性、非易失性、时变性。 数据仓库的体系结构通常包含4个层次ÿ…...
c语言实现简单的string
文章目录 前言一、注意事项二、代码valgrind扫描总结 前言 在c语言中利用面向对象的编程方式,实现类似c中的string类。 一、注意事项 所有与string结构体相关的函数全都没有返回值。 在c中,当产生临时对象时编译器会自动的加入析构函数,销毁…...
老师应具备什么样的心理素质
老师,一个充满智慧与挑战的职业,就像园丁,用无私的爱和耐心,滋养着每一颗渴望知识的幼苗。那么,作为教育从业者,要具备哪些心理素质呢? 强大的情绪管理能力 老师的工作绝非一帆风顺。在教育学生…...
C语言——单链表(增删改查)
C语言——单链表(增删改查) 一链表一 #include<stdio.h> #include<stdlib.h> #include<string.h>typedef struct Test {int data;struct Test *next; }Link;Link *headNULL;Link* creatHead(Link* head); void AddLinkNode(Link* head,Link newnode); vo…...
Jenkins 保姆级教程
一、什么是流水线 jenkins 有 2 种流水线分为声明式流水线与脚本化流水线,脚本化流水线是 jenkins 旧版本使用的流水线脚本,新版本 Jenkins 推荐使用声明式流水线。文档只介绍声明流水线。 声明式流水线 在声明式流水线语法中,流水线过程定…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...
