当前位置: 首页 > article >正文

Spring Cloud Gateway 的执行链路详解

Spring Cloud Gateway 的执行链路详解


🎯 核心目标

明确 Spring Cloud Gateway 的请求处理全过程(从接收到请求 → 到转发 → 到返回响应),方便你在合适的生命周期节点插入你的逻辑。


🧱 核心执行链路图(执行顺序)

┌──────────────┐
│ 客户端请求   │
└────┬─────────┘↓
┌────┴─────────────┐
│ Netty HttpServer │ ←→ Reactor Netty(非阻塞)
└────┬─────────────┘↓
┌────┴────────────┐
│ HttpRoutePredicateEvaluator │ 路由匹配
└────┬────────────┘↓
┌────┴────────────┐
│ GlobalFilter Chain       │ ← 【你做定制的核心入口】
│  ├── GlobalFilter (Ordered)
│  ├── CustomFilter
│  └── FilterChain
└────┬────────────┘↓
┌────┴────────────┐
│ WebClient 调用目标服务  │(负载均衡、路由转发)
└────┬────────────┘↓
┌────┴────────────┐
│ 响应处理(过滤器链倒序) │
└────────────┬────┘↓客户端收到响应

🔄 Gateway 核心处理流程分阶段讲解


🔹 1. 请求接入:Netty 接收

  • Gateway 使用 Reactor Netty 构建 Server,所有请求是异步 + 非阻塞处理。
  • 请求通过 HttpServer 被接收并封装成 ServerWebExchange 对象(封装 request + response + 路由信息 + 上下文等)。

🔹 2. Route 匹配阶段(断言匹配)

配置文件中的路由定义,如:

spring:cloud:gateway:routes:- id: user_routeuri: http://user-servicepredicates:- Path=/api/user/**

这一步是通过 RoutePredicateHandlerMapping 完成:

✅ 判断当前请求路径是否匹配配置中的 predicates

📌 你可以实现 RoutePredicateFactory 来定制更复杂的匹配规则,例如 IP、请求头、时间段等


🔹 3. 全局过滤器链(GlobalFilter)执行阶段

这是你进行自定义操作的核心切入点

内置常用过滤器有:
过滤器类名作用顺序(order)
RemoveRequestHeaderGatewayFilter删除请求头-1
AddRequestHeaderGatewayFilter添加请求头0
RetryGatewayFilter自动重试-2
RequestRateLimiterGatewayFilter限流(结合 Redis)-10
HystrixGatewayFilter熔断降级-100

你也可以实现自己的 GlobalFilterGatewayFilterFactory

示例:自定义 GlobalFilter
@Component
@Order(-1) // 顺序越小越先执行
public class AuthGlobalFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getHeaders().getFirst("Authorization");if (!StringUtils.hasText(token) || !checkToken(token)) {// 拦截请求,返回 401exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange); // 放行}
}

🔹 4. 网关调用下游服务(转发阶段)

  • 实际调用目标服务(通过 WebClient 发出请求)
  • 如果配置了 lb:// 前缀,会使用 Spring Cloud LoadBalancer 做负载均衡(Nacos、Eureka 都支持)
uri: lb://order-service

🔹 5. 响应返回时的处理(倒序执行 Filter)

在响应返回时,全局过滤器链会逆序执行,可以在这里做一些响应增强:

  • 添加响应头
  • 日志记录(返回码、耗时)
  • 数据脱敏
  • 响应体改写(结合缓存)

示例:记录响应耗时

@Component
@Order(1)
public class TimeLogFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {long start = System.currentTimeMillis();return chain.filter(exchange).then(Mono.fromRunnable(() -> {long cost = System.currentTimeMillis() - start;System.out.println("接口请求耗时:" + cost + "ms");}));}
}

🔧 常见自定义操作建议位置对照表

功能推荐实现方式说明
请求日志记录GlobalFilter获取 request 信息,记录 URI/参数/IP
参数校验(如签名)GlobalFilter拦截非法请求
JWT 鉴权GlobalFilter可选使用 Reactor 模式解析 token
限流(IP/QPS)Redis + 自定义 Filter或使用 Spring 官方限流 Filter
熔断降级Resilience4j/Hystrix可集成入 Gateway Filter
黑名单拦截GlobalFilter + Redis校验 IP 是否在黑名单
响应体改写RewriteResponseBodyFilter需要缓存响应流
请求体改写RewriteRequestBodyFilter非常规操作,需 cache request body

📌 注意事项:Netty + 响应式陷阱

Spring Cloud Gateway 是响应式编程,与传统 Servlet 不一样:

注意点说明
Request Body 只能读取一次需要使用 CachedBodyOutputMessage 缓存
Response 体也只能写一次修改响应需用 BodyInserter
操作是异步链式的推荐使用 Mono.defer()then() 等操作链
使用 @Order 控制顺序值越小越早执行,如认证应在最前面执行

🎁 Bonus:完整请求链源码入口参考(Spring Cloud Gateway)

模块类名说明
spring-cloud-gatewayGatewayAutoConfiguration自动装配
RoutePredicateHandlerMapping匹配路由
FilteringWebHandler核心过滤链执行器
GlobalFilter全局过滤器接口
GatewayFilterFactory局部路由过滤器工厂接口

相关文章:

Spring Cloud Gateway 的执行链路详解

Spring Cloud Gateway 的执行链路详解 &#x1f3af; 核心目标 明确 Spring Cloud Gateway 的请求处理全过程&#xff08;从接收到请求 → 到转发 → 到返回响应&#xff09;&#xff0c;方便你在合适的生命周期节点插入你的逻辑。 &#x1f9f1; 核心执行链路图&#xff08;执…...

鸿蒙应用(医院诊疗系统)开发篇2·Axios网络请求封装全流程解析

一、项目初始化与环境准备 1. 创建鸿蒙工程 src/main/ets/ ├── api/ │ ├── api.ets # 接口聚合入口 │ ├── login.ets # 登录模块接口 │ └── request.ets # 网络请求核心封装 └── pages/ └── login.ets # 登录页面逻辑…...

突发重磅消息!!!CVE项目将被取消?

突发重磅消息&#xff01;&#xff01;&#xff01;CVE项目将被取消&#xff1f;突发&#xff01;来自可靠消息来源。MITRE 对 CVE 项目的支持将于明天到期。附件信件已发送给 CVE 董事会成员。https://mp.weixin.qq.com/s/N3qkiHaDfzDuBMK3JbBCjw...

详解与FTP服务器相关操作

目录 什么是FTP服务器 搭建FTP服务器相关 ​编辑 Unity中与FTP相关的类 上传文件到FTP服务器 使用FTP服务器上传文件的关键点 开始上传 从FTP服务器下载文件到客户端 使用FTP下载文件的关键点 开始下载 关于FTP服务器的其他操作 将文件的上传&#xff0c;下载&…...

远程登录一个Linux系统,如何用命令快速知道该系统属于Linux的哪个发行版,以及该服务器的各种配置参数,运行状态?

远程登录一个Linux系统&#xff0c;如何用命令快速知道该系统属于Linux的哪个发行版&#xff0c;以及该服务器的各种配置参数&#xff0c;运行状态&#xff1f; 查看Linux发行版信息 查看发行版名称和版本&#xff1a; cat /etc/*-release或 lsb_release -a查看内核版本&#…...

解决 .Net 6.0 项目发布到IIS报错:HTTP Error 500.30

今天在将自己开发许久的项目上线的时候&#xff0c;发现 IIS 发布后请求后端老是报一个 HTTP Error 500.30 的异常&#xff0c;如下图所示。   后来仔细调查了一下发现是自己的程序中写了 UseStaticFiles 的依赖注入&#xff0c;这个的主要作用就是发布后端后&#xff0c;想…...

STM32F103_HAL库+寄存器学习笔记16 - 监控CAN发送失败(轮询方式)

导言 《STM32F103_HAL库寄存器学习笔记15 - 梳理CAN发送失败时&#xff0c;涉及哪些寄存器》从上一章节看到&#xff0c;当CAN消息发送失败时&#xff0c;CAN错误状态寄存器ESR的TEC会持续累加&#xff0c;LEC等于0x03&#xff08;ACK错误&#xff09;。本次实验的目的是编写一…...

Java并发-AQS框架原理解析与实现类详解

什么是AQS&#xff1f; AQS&#xff08;AbstractQueuedSynchronizer&#xff09;是Java并发包&#xff08;JUC&#xff09;的核心基础框架&#xff0c;它为构建锁和同步器提供了高效、灵活的底层支持。本文将从设计原理、核心机制及典型实现类三个维度展开&#xff0c;帮助读者…...

实现定长的内存池

池化技术 所谓的池化技术&#xff0c;就是程序预先向系统申请过量的资源&#xff0c;然后自己管理起来&#xff0c;以备不时之需。这个操作的价值就是&#xff0c;如果申请与释放资源的开销较大&#xff0c;提前申请资源并在使用后并不释放而是重复利用&#xff0c;能够提高程序…...

vs2022使用git方法

1、创建git 2、在cmd下执行 git push -f origin master &#xff0c;会把本地代码全部推送到远程&#xff0c;同时会覆盖远程代码。 3、需要设置【Git全局设置】&#xff0c;修改的代码才会显示可以提交&#xff0c;否则是灰色的不能提交。 4、创建的分支&#xff0c;只要点击…...

Mysql中表的使用(3)

目录 1.updata的使用 2.delete(删除表中数据)drop&#xff08;删除表&#xff09; 数据库的约束 1.NOT NULL 指定列不能为空 2.UNIQUE指定列唯一 3.DEFAULT(默认值) 4.PRIMARY KEY 5.自增主键 1.updata的使用 1.0update 表名 set 列名x where 列名y; 2.0update 表名 s…...

BUUCTF-Web(1-20)

目录 一.SQL注入 (1)[极客大挑战 2019]EasySQL 万能密码 (7)[SUCTF 2019]EasySQL 堆叠注入 解一&#xff1a; 解二&#xff1a; (10)[强网杯 2019]随便注 堆叠注入 解一&#xff1a; 解二&#xff1a; 解三&#xff1a; (8)[极客大挑战 2019]LoveSQL 联…...

Uniapp:确认框

目录 一、 出现场景二、 效果展示三、具体使用 一、 出现场景 在项目的开发中&#xff0c;会经常出现删除数据的情况&#xff0c;如果直接删除的话&#xff0c;可能会存在误删&#xff0c;用户体验不好&#xff0c;所以需要增加一个消息提示&#xff0c;提醒用户是否删除。 二…...

【前端网络请求入门】XMLHttpRequest与Fetch保姆级教程

新手学前端时&#xff0c;经常会被「如何让网页和服务器说话」难住。今天我们用最通俗的语言&#xff0c;把浏览器最常用的两种网络请求方式——XMLHttpRequest和Fetch讲清楚&#xff0c;还会带完整的代码示例&#xff0c;跟着敲一遍就能上手&#xff01; 一、先搞懂「网络请求…...

力扣热题100—滑动窗口(c++)

3.无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 unordered_set<char> charSet; // 用于保存当前窗口的字符int left 0; // 窗口左指针int maxLength 0; // 最长子串的长度for (int right 0; right < s.siz…...

实验四 中断实验

一、实验目的 掌握中断服务程序的编写。 二、实验电路 三、实验内容 1&#xff0e;实验用PC机内部的中断控制器8259A&#xff0c;中断源用TPC-ZK实验箱上的单脉冲电路&#xff0c;将单脉冲电路的输出接中断请求信号IRQ&#xff0c;每按一次单脉冲按键产生一次…...

腾势品牌欧洲市场冲锋,科技豪华席卷米兰

在时尚与艺术的交汇点&#xff0c;米兰设计周的舞台上&#xff0c;一场汽车界的超级风暴正在酝酿&#xff0c;腾势品牌如一头勇猛无畏的雄狮&#xff0c;以雷霆万钧之势正式向欧洲市场发起了冲锋。其最新力作——腾势Z9GT的登场&#xff0c;仿佛是一道闪电划破夜空&#xff0c;…...

第五阶段:项目实践与后续学习指引

模块 10&#xff1a;综合项目实践 在这个模块中&#xff0c;我们将通过实际项目来综合运用前面所学的 Python 知识。我们会选择一个命令行记事本应用作为主要示例&#xff0c;同时简要介绍其他项目的思路。 项目&#xff1a;命令行记事本应用 1. 项目规划 良好的项目规划是…...

MoogDB数据库日常维护技巧与常见问题解析

在当今的数据驱动世界中&#xff0c;数据库作为信息存储与管理的核心组件&#xff0c;扮演着举足轻重的角色。MoogDB作为一款高性能、易扩展的数据库解决方案&#xff0c;越来越受到开发者和企业的青睐。为了确保MoogDB的稳定性与高性能&#xff0c;定期的日常维护及对常见问题…...

Java 中的各种锁详解

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

多店铺商城_多商户商城系统源码_免费开源!

在电商行业快速发展的今天&#xff0c;多店铺商城系统&#xff08;B2B2C模式&#xff09;已成为企业实现平台化运营的核心工具&#xff0c;就像我们平时用的淘宝&#xff0c;京东那样。如果你想做一个电商平台就需要这种多店铺商城系统。 本文将深入探讨多商户商城系统的核心功…...

【2025年泰迪杯数据挖掘挑战赛】A题 数据分析+问题建模与求解+Python代码直接分享

目录 2025年泰迪杯数据挖掘挑战赛A题完整论文&#xff1a;建模与求解Python代码1问题一的思路与求解1.1 问题一的思路1.1.1对统计数据进行必要说明&#xff1a;1.1.2统计流程&#xff1a;1.1.3特殊情况的考虑&#xff1a; 1.2 问题一的求解1.2.1代码实现1.2.2 问题一结果代码分…...

NO.95十六届蓝桥杯备战|图论基础-单源最短路|负环|BF判断负环|SPFA判断负环|邮递员送信|采购特价产品|拉近距离|最短路计数(C++)

P3385 【模板】负环 - 洛谷 如果图中存在负环&#xff0c;那么有可能不存在最短路。 BF算法判断负环 执⾏n轮松弛操作&#xff0c;如果第n轮还存在松弛操作&#xff0c;那么就有负环。 #include <bits/stdc.h> using namespace std;const int N 2e3 10, M 3e3 1…...

ROS2模块库概览

一、核心通信与基础库&#xff08;最常用&#xff09; 客户端库 rclcpp (ROS Client Library for C) 核心API&#xff1a;create_node(), create_publisher(), create_subscription()高级特性&#xff1a; 生命周期节点&#xff1a;通过rclcpp_lifecycle实现configure/activate…...

在机器视觉检测中为何选择线阵工业相机?

线阵工业相机&#xff0c;顾名思义是成像传感器呈“线”状的。虽然也是二维图像&#xff0c;但极宽&#xff0c;几千个像素的宽度&#xff0c;而高度却只有几个像素的而已。一般在两种情况下使用这种相机&#xff1a; 1. 被测视野为细长的带状&#xff0c;多用于滚筒上检测的问…...

Linux应急中常用命令

pwdx {pid} 提供进程的 当前工作目录&#xff0c;即进程正在操作的目录。它显示的是进程的运行时工作目录&#xff0c;而不是启动时的可执行文件路径。等同于ls -al /proc//cwdps -aux 和 top 都是用来查看 Linux 系统中进程的命令&#xff0c;但它们的功能、输出格式和使用场景…...

Node.js 文件读取与复制相关内容

Node.js 文件读取与复制相关内容的系统总结&#xff0c;包括 同步读取、异步读取、流式读取、复制操作、两者对比及内存测试。 &#x1f9e9; 一、Node.js 文件读取方式总结 Node.js 使用 fs&#xff08;文件系统&#xff09;模块进行文件操作&#xff1a; 1. 同步读取&#…...

数据结构-串

串是数据结构中一种重要的数据类型&#xff0c;广泛应用于文本处理、信息检索等领域。本文将从串的基本概念、存储实现、应用举例以及总结核心知识点四个方面进行详细讲解&#xff0c;帮助大家更好地理解和掌握串这一数据结构。 一、串的基本概念及其抽象数据类型 1.1 串的定…...

Windows 下 MongoDB ZIP 版本安装指南

在开发和生产环境中&#xff0c;MongoDB 是一种非常流行的 NoSQL 数据库&#xff0c;以其灵活性和高性能而受到开发者的青睐。对于 Windows 用户来说&#xff0c;MongoDB 提供了多种安装方式&#xff0c;其中 ZIP 版本因其灵活性和轻量级的特点&#xff0c;成为很多开发者的首选…...

在 Spring Boot 中实现服务器端推送(SSE):两种方法的比较与实践

在现代 Web 应用中&#xff0c;实时数据推送是一个常见的需求。无论是实时消息通知、股票行情更新&#xff0c;还是在线游戏的实时数据交互&#xff0c;服务器端推送&#xff08;Server-Sent Events&#xff0c;简称 SSE&#xff09;都是一种高效且易于实现的解决方案。在 Spri…...