SpringCloud - Gateway 网关
前言
该博客为Sentinel学习笔记,主要目的是为了帮助后期快速复习使用
学习视频:7小快速通关SpringCloud
辅助文档:SpringCloud快速通关
源码地址:cloud-demo
一、简介
官网:https://spring.io/projects/spring-cloud-gateway
Spring Cloud Gateway 是基于 Spring 生态系统(包括 Spring 6、Spring Boot 3 和 Project Reactor)构建的 API 网关。它旨在为 API 提供简单而有效的路由,并处理诸如安全性、监控/指标和弹性等跨领域关注点。

1.1 主要特性
- 构建于 Spring Framework 和 Spring Boot 之上: 利用
Spring强大的生态系统,确保与其他Spring项目的无缝集成。 - 灵活的路由匹配: 能够基于任何请求属性(如路径、主机、方法等)定义路由规则。
- 丰富的谓词和过滤器: 为每个路由提供特定的谓词和过滤器,方便实现复杂的路由逻辑和请求/响应的修改。
- 断路器集成: 与
Hystrix等断路器库集成,增强系统的弹性和容错能力。 - 服务发现集成: 与
Spring Cloud DiscoveryClient集成,实现动态路由和负载均衡。 - 请求速率限制: 提供请求速率限制功能,保护后端服务免受流量突增的影响。
- 路径重写: 支持对请求路径进行重写,满足不同的路由需求。
1.2 主要功能

1.3 版本选择
Spring Cloud Gateway 的两个版本主要区别在于它们的编程模型和适用场景:
- Reactive Server(响应式版本):
- 基于
WebFlux框架,使用响应式编程模型。 - 支持完全非阻塞的
I/O操作,可以提高吞吐量和降低延迟。 - 适用于构建高性能、高并发的微服务架构。
- 与现代的响应式编程库(如
Reactor)兼容。
- 基于
- Server MVC(传统阻塞式版本):
- 基于
Spring MVC框架,使用传统的同步阻塞I/O模型。 - 更适合与现有的
Spring MVC应用程序集成。 - 可能在高并发场景下的性能不如响应式版本。
- 基于
推荐使用响应式的Gateway

二、快速入门
2.1 需求
- 客户端发送
/api/order/**转到service-order - 客户端发送
/api/product/**转到service-product - 以上转发有负载均衡效果

2.2 创建模块
创建gateway模块,引入 spring-cloud-starter-gateway、spring-cloud-starter-alibaba-nacos-discovery、spring-cloud-starter-loadbalancer
<!-- gateway网关 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- 服务发现 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--loadbalancer负载均衡--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
添加主程序GatewayMainApplication
@SpringBootApplication
public class GatewayMainApplication {public static void main(String[] args) {SpringApplication.run(GatewayMainApplication.class, args);}
}
添加配置文件application.yml
# 服务端口
server:port: 80spring:application:name: gateway # 服务名称cloud:nacos:server-addr: 127.0.0.1:8848 # nacos地址(默认)
这里可以启动微服务gateway、service-order、service-product,确保在Nacos控制台可以看到

2.3 改造微服务
创建 application-route.yml,为 service-order、service-prduct 添加 /api基础路径
spring:cloud:gateway:routes:- id: order-routeuri: lb://service-order # lb(LoadBalance)代表负载均衡predicates: # 路径断言规则- Path=/api/order/** # 路径匹配- id: product-routeuri: lb://service-productpredicates:- Path=/api/product/**
并且需要在application.yml中启用 application-route.yml才能生效
spring:profiles:include: route # 启用route
2.4 测试
在浏览器中输入http://localhost/api/order/readDb,通过网关访问 service-order微服务的接口

2.5 基础原理
- 请求处理:
- 用户请求首先到达
Gateway。
- 用户请求首先到达
- 路由规则(Route):
- 网关根据预定义的路由规则(Route)来决定请求的转发路径。
- 每个路由规则包含三个主要部分:
- Predicate 断言:用于匹配请求的条件,如路径、头信息、查询参数等。
- URI 目的地:匹配请求后,请求将被转发到的目标地址。
- Filter 过滤器:在请求转发前后执行的一系列过滤器链,用于修改请求/响应、进行认证等。
- 过滤器链(Filter Chain):
- 请求在转发到目的地之前,会先经过一系列过滤器(Filter)的处理。
- 过滤器可以执行各种任务,如日志记录、请求修改、认证授权等。
- 过滤器按照定义的顺序执行,形成一个过滤器链。
- 转发请求:
- 经过过滤器链处理后,请求被转发到最终的目的地(服务提供者)。
- 响应处理:
- 目的地处理完请求后,将响应返回给网关。
- 响应同样会经过过滤器链的处理,然后返回给用户。

三、Predicate - 断言
3.1 断言写法
3.1.1 短写法
快捷方式配置由过滤器名称识别,后跟等号 (=),后跟用逗号 (,) 分隔的参数值。
# 断言短写法
spring:cloud:gateway:routes:- id: order-routeuri: lb://service-order # lb(LoadBalance)代表负载均衡predicates: # 路径断言规则- Path=/api/order/** # 路径匹配
3.1.2 全写法
完全展开的参数看起来更像是带有名称/值对的标准 yaml 配置。通常,将有一个 name 键和一个 args 键。args 键是用于配置谓词或筛选条件的键值对的映射。
# 断言全写法
spring:cloud:gateway:routes:- id: order-routeuri: lb://service-order # lb(LoadBalance)代表负载均衡predicates:- name: Path # 路径断言args: # 参数pattern: /api/order/** # 匹配路径matchTrailingSlash: true # 匹配尾部斜杠
3.2 断言工厂


3.3 自定义断言工厂
创建XxxRoutePredicateFactory继承AbstractRoutePredicateFactory类
/*** Vip断言工厂*/
@Component
public class VipRoutePredicateFactory extends AbstractRoutePredicateFactory<VipRoutePredicateFactory.Config> {public VipRoutePredicateFactory() {super(Config.class);}// 配置参数的顺序,为短写法准备@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("param", "value");}// 断言逻辑@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return new GatewayPredicate() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {// localhost/search?q=haha&user=jyhString first = serverWebExchange.getRequest().getQueryParams().getFirst(config.param);return StringUtils.hasText(first) && first.equals(config.value);}};}/*** 可以配置的参数*/@Validatedpublic static class Config {@NotEmptyprivate String param;@NotEmptyprivate String value;public @NotEmpty String getParam() {return param;}public void setParam(@NotEmpty String param) {this.param = param;}public @NotEmpty String getValue() {return value;}public void setValue(@NotEmpty String value) {this.value = value;}}
}
编写配置文件
spring:cloud:gateway:routes:- id: bing-routeuri: https://cn.bing.com/ # 跳转地址predicates:- name: Path # 路径断言args:patterns: /search- name: Query # 查询参数断言args:param: q # 参数名regexp: haha # 正则表达式
# - Vip=user,jyh- name: Vip # 自定义Vip断言args:param: uservalue: jyh
四、Filter - 过滤器


4.1 路由重写 - RewritePath

spring:cloud:gateway:routes:- id: order-routeuri: lb://service-order # lb(LoadBalance)代表负载均衡predicates:- name: Path # 路径断言args: # 参数pattern: /api/order/** # 匹配路径matchTrailingSlash: true # 匹配尾部斜杠filters:- RewritePath=/api/order/?(?<segment>.*), /$\{segment} # 重写路径
RewritePath=/api/order/?(?<segment>.*), /$\{segment}这个规则的意思是:
如果请求路径以 /api/order/ 开头,且后面有任意内容(如 /api/order/123),则会将路径重写为 /123 ,即删除 /api/order/ 部分,只保留后面的内容。
4.2 添加响应请求头 - AddResponseHeader
spring:cloud:gateway:routes:- id: order-routeuri: lb://service-order # lb(LoadBalance)代表负载均衡predicates:- name: Path # 路径断言args: # 参数pattern: /api/order/** # 匹配路径matchTrailingSlash: true # 匹配尾部斜杠filters:- AddResponseHeader=X-Response-Abc, 123 # 添加响应请求头

4.3 默认filter - Default Filters
所有路由规则都生效默认filter里面配置的规则
spring:cloud:gateway:routes:- id: order-routeuri: lb://service-order # lb(LoadBalance)代表负载均衡predicates:- name: Path # 路径断言args: # 参数pattern: /api/order/** # 匹配路径matchTrailingSlash: true # 匹配尾部斜杠filters:- RewritePath=/api/order/?(?<segment>.*), /$\{segment} # 重写路径- id: product-routeuri: lb://service-productpredicates:- Path=/api/product/**filters:- RewritePath=/api/product/?(?<segment>.*), /$\{segment} # 重写路径default-filters: # 默认过滤器- AddResponseHeader=X-Response-Abc, 123 # 添加响应头
4.4 全局filter - Global Filters
/*** 全局过滤器 - 耗时统计* @author jiangyiheng*/
@Slf4j
@Component
public class RtGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String uri = exchange.getRequest().getURI().toString();long start = System.currentTimeMillis();log.info("请求开始【{}】开始时间:{}", uri, start);// ======================以上是前置逻辑======================Mono<Void> filter = chain.filter(exchange).doFinally((result)->{// ======================以下是后置逻辑======================long end = System.currentTimeMillis();log.info("请求结束【{}】结束时间:{} ,耗时:{}ms", uri, end, end - start);}); // 放行return filter;}// 优先级@Overridepublic int getOrder() {return 0;}
}

4.5 自定义过滤器
创建一个XxxGatewayFilterFactory类继承AbstractNameValueGatewayFilterFactory工厂
/*** 自定义过滤器-令牌网关过滤器*/
@Component
public class OneTokenGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {@Overridepublic GatewayFilter apply(NameValueConfig config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 每次响应前,添加一个一次性令牌,支持 uuid,jwt等各种格式return chain.filter(exchange).then(Mono.fromRunnable(()->{ServerHttpResponse response = exchange.getResponse();String value = config.getValue();if ("uuid".equalsIgnoreCase(value)) {value = UUID.randomUUID().toString();}if ("jwt".equalsIgnoreCase(value)) {value = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";}response.getHeaders().add(config.getName(), value);}));}};}
}

五、CORS - 跨域处理
5.1 全局跨域
spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowed-origin-patterns: '*' # 允许所有跨域allowed-methods: '*' # 允许所有请求方式allowed-headers: '*' # 允许所有头
5.2 局部跨域
spring:cloud:gateway:routes:- id: cors_routeuri: https://example.orgpredicates:- Path=/service/**metadata:cors:allowedOrigins: '*'allowedMethods:- GET- POSTallowedHeaders: '*'maxAge: 30
面试题:微服务之间的调用经过网关吗?
微服务之间的调用一般不会经过网关。网关主要用于处理外部请求,负责路由、认证、限流等功能。而微服务之间的通信通常通过服务发现和负载均衡直接进行,不需要经过网关。然而,在某些特殊情况下,如果需要统一管理或控制,微服务之间的调用也可能通过网关。
相关文章:
SpringCloud - Gateway 网关
前言 该博客为Sentinel学习笔记,主要目的是为了帮助后期快速复习使用 学习视频:7小快速通关SpringCloud 辅助文档:SpringCloud快速通关 源码地址:cloud-demo 一、简介 官网:https://spring.io/projects/spring-clou…...
【JVM详解五】JVM性能调优
示例: 配置JVM参数运行 #前台运行 java -XX:MetaspaceSize-128m -XX:MaxMetaspaceSize-128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio8 - XX:UseConcMarkSweepGC -jar /jar包路径 #后台运行 nohup java -XX:MetaspaceSize-128m -XX:MaxMetaspaceS…...
基于 STM32 平台的音频特征提取与歌曲风格智能识别系统
标题:基于 STM32 平台的音频特征提取与歌曲风格智能识别系统 内容:1.摘要 摘要:本文介绍了一种基于 STM32 平台的音频特征提取与歌曲风格智能识别系统。该系统通过对音频信号进行特征提取和分析,实现了对歌曲风格的自动识别。在特征提取方面,…...
DeepSeek:搅动人工智能产业风云的鲶鱼效应深度解读
我的个人主页 我的专栏:人工智能领域,希望能帮助到大家!!!点赞❤ 收藏❤ 引言 在当今科技飞速发展的时代,人工智能(AI)无疑是最为耀眼的领域之一。众多技术与平台如繁星般涌现&a…...
一觉醒来全球编码能力下降100000倍,新手小白的我决定科普C语言——三子棋游戏实现
硬控我一上午,小编还是太菜了,大家可以自行升级电脑难度,也可以升级游戏到五子棋 1.game.h #pragma once #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 3 #define COL 3//初始化棋盘 void InitBoa…...
学习 URL 传参中哪些字符是支持的,哪些是不支持的
URL 的结构 URL 由多个部分组成,包括协议、域名、路径、查询参数和片段标识符,其中,查询参数部分就是问号后面的内容,这部分使用键值对,中间用 & 分隔。比如,http://example.com/path?key1value1&…...
bingAI生成的易语言编程基础
易语言编程基础 易语言(EPL)是一种基于中文的编程语言,旨在简化编程学习过程,特别适合初学者和有一定编程基础的开发者。它通过中文关键词和语法,降低了编程的门槛,使得代码更加直观易懂。 示例ÿ…...
HTML应用指南:利用POST请求获取接入比亚迪业态的充电桩位置信息
在新能源汽车快速发展的今天,充电桩的分布和可用性成为了影响用户体验的关键因素之一。比亚迪作为全球领先的新能源汽车制造商,不仅在车辆制造方面取得了卓越成就,也在充电基础设施建设上投入了大量资源。为了帮助用户更方便地找到比亚迪充电桩的位置,本篇文章,我们将探究…...
高斯消元法及其C++实现
深入浅出高斯消元法及其C实现 本文章代码由博主编写但是文章由ChatGPT-o1-mini生成 博客食用更佳 在计算机算法竞赛中,线性方程组的求解是一个常见且基础的问题。高斯消元法作为一种经典的算法,因其高效和直观的特性,广泛应用于各种编程竞赛和…...
DeepSeek AI R1推理大模型API集成文档
DeepSeek AI R1推理大模型API集成文档 引言 随着自然语言处理技术的飞速发展,大语言模型在各行各业的应用日益广泛。DeepSeek R1作为一款高性能、开源的大语言模型,凭借其强大的文本生成能力、高效的推理性能和灵活的接口设计,吸引了大量开发…...
【算法-动态规划】、魔法卷轴: 两次清零机会整个数组最大累加和
【算法-动态规划】、魔法卷轴: 两次清零机会整个数组最大累加和 文章目录 一、dp1.1 题意理解1.2 整体思路1.3 具体思路1.4 代码 二、多语言解法 一、dp 1.1 题意理解 nums 数组, 有正负0, 使用最多两次魔法卷轴, 希望使数组整体的累加和尽可能大. 求尽可能大的累加和 其实就…...
【R】Dijkstra算法求最短路径
使用R语言实现Dijkstra算法求最短路径 求点2、3、4、5、6、7到点1的最短距离和路径 1.设置data,存放有向图信息 data中每个点所在的行序号为起始点序号,列为终点序号。 比如:值4的坐标为(1,2)即点1到点2距离为4;值8的坐标为(6,7)…...
深入浅出:探索 DeepSeek 的强大功能与应用
深入浅出:探索 DeepSeek 的强大功能与应用 在人工智能技术飞速发展的今天,自然语言处理(NLP)作为其重要分支,正逐渐渗透到我们生活的方方面面。DeepSeek 作为一款功能强大的 NLP 工具,凭借其易用性和高效性…...
西门子S7-200 PLC串口PPI转以太网通讯的模块链接方式
项目背景 某汽车零部件生产车间有30台自动化生产设备,控制系统采用西门子S7-200系列的CPU226。此前,设备的一个通讯端口用于和变频器进行自由口通讯,另一个通讯端口连接着一台昆仑通态触摸屏作为人机界面。车间计划进行智能化升级ÿ…...
win10向windows server服务器传输文件
win10向windows server服务器传输文件 遇到无法直接拖动文件进行传输时 解决方案: 1.点击显示选项 2.点击本地资源-详细信息 3.在窗口中选择你需要共享的磁盘 4.然后远程连接到Windows server服务器 5.登录Windows server服务器后,在此电脑下就能看…...
git服务器搭建,gitea服务搭建,使用systemclt管理服务
文章目录 页面展示使用二进制文件安装git服务下载选择架构使用wget下载安装 验证 GPG 签名服务器设置准备环境创建systemctl文件 备份与恢复备份命令 (dump)恢复命令 (restore) 页面展示 使用二进制文件安装git服务 所有打包的二进制程序均包含 SQLite,MySQL 和 Po…...
Mybatis快速入门与核心知识总结
Mybatis 1. 实体类(Entity Class)1.1 实体类的定义1.2 简化编写1.2.1 Data1.2.2 AllArgsConstructor1.2.3 NoArgsConstructor 2. 创建 Mapper 接口2.1 Param2.2 #{} 占位符2.3 SQL 预编译 3. 配置 MyBatis XML 映射文件(可选)3.1 …...
用docker在本地用open-webui部署网页版deepseek
前置条件 用Ollama在本地CMD窗口运行deepseek大模型-CSDN博客文章浏览阅读109次,点赞5次,收藏2次。首次运行需要下载deepseek的大模型包(大约5GB,根据本地网速的不同在半个小时到几个小时之间下载完成) ,并…...
2025.2.8——一、[护网杯 2018]easy_tornado tornado模板注入
题目来源:BUUCTF [护网杯 2018]easy_tornado 目录 一、打开靶机,整理信息 二、解题思路 step 1:分析已知信息 step 2:目标——找到cookie_secret step 3:构造payload 三、小结 一、打开靶机,整理信…...
前端实现在PDF上添加标注(1)
前段时间接到一个需求,用户希望网页上预览PDF,同时能在PDF上添加文字,划线,箭头和用矩形框选的标注,另外还需要对已有的标注进行修改,删除。 期初在互联网上一通搜索,对这个需求来讲发现了两个问…...
【CXX-Qt】1.1 Rust中的QObjects
本文涉及到了使用CXX-Qt将Rust、C和QML集成到Qt应用程序中的各个方面。下面,我将提供一个简单的示例,演示如何使用CXX-Qt来创建一个Rust结构体并将其作为QObject子类暴露给C和QML。 一、设置CXX-Qt环境 首先,确保您已经安装了Rust、CXX和CX…...
操作系统中的任务调度算法
一、引言 在操作系统中,任务调度算法是核心组件之一,它负责合理分配有限的 CPU 资源,以确保系统的高效运行和良好的用户体验。任务调度的目标是实现公平性、最小化等待时间、提高系统吞吐量,并最大化 CPU 的利用率。不同的任务调…...
GitCode 助力 Easy-Es,革新 Elasticsearch 开发体验
项目仓库(点击阅读原文链接可直达) https://gitcode.com/dromara/easy-es 项目背景:填补 Elasticsearch ORM 框架空白 在 Java 开发领域,Excel 和 Elasticsearch 的代码编写难度一直名列前茅,尤其是 Elasticsearch&a…...
线程同步(互斥锁与条件变量)
文章目录 1、为什么要用互斥锁2、互斥锁怎么用3、为什么要用条件变量4、互斥锁和条件变量如何配合使用5、互斥锁和条件变量的常见用法 参考资料:https://blog.csdn.net/m0_53539646/article/details/115509348 1、为什么要用互斥锁 为了使各线程能够有序地访问公共…...
EF Core中实现值对象
目录 值对象优点 值对象的需求 值类型的实现 值类型GEO的实现 值类型MultilingualString的实现 案例:构建表达式树,简化值对象的比较 值对象优点 把有紧密关系的属性打包为一个类型把领域知识放到类的定义中 class shangjia {long id;string nam…...
《从入门到精通:蓝桥杯编程大赛知识点全攻略》(十一)-回文日期、移动距离、日期问题
前言 在这篇博客中,我们将通过模拟的方法来解决三道经典的算法题:回文日期、移动距离和日期问题。这些题目不仅考察了我们的基础编程能力,还挑战了我们对日期处理和数学推理的理解。通过模拟算法,我们能够深入探索每个问题的核心…...
Kubernetes 最佳实践:Top 10 常见 DevOps/SRE 面试问题及答案
1. 如何在 Kubernetes 中设置资源请求和限制? 资源请求确保容器有最小资源量(CPU/内存),而限制则强制容器消耗的最大资源量。这有助于高效资源分配并防止资源争用。 示例: resources:requests:memory: "256Mi&…...
Docker Compose介绍及安装使用MongoDB数据库详解
在现代容器化应用部署中,Docker Compose是一种非常实用的工具,它允许我们通过一个docker-compose.yml文件来定义和运行多容器应用程序。然而,除了Docker之外,Podman也提供了类似的工具——Podman Compose,它允许我们在…...
科普:数据仓库中的“指标”和“维度”
在数据仓库中,指标和维度是两个核心概念,它们对于数据分析和业务决策至关重要。以下是对这两个概念的分析及举例说明: 一、指标 定义: 指标是用于衡量业务绩效的关键数据点,通常用于监控、分析和优化企业的运营状况。…...
11.swagger使用
菜单位置 未登录接口会返回401 登录的token存储的位置 配置文件swagger配置中将/dev-api修改/...
