SpringCloud网关:Gateway路由配置与过滤器链

在这里插入图片描述

文章目录

    • 引言
    • 一、Gateway基本架构
    • 二、路由配置方式
      • 2.1 配置文件方式
      • 2.2 Java代码方式
    • 三、内置断言工厂
    • 四、内置过滤器工厂
      • 4.1 请求路径相关过滤器
      • 4.2 请求和响应头过滤器
      • 4.3 功能性过滤器
    • 五、自定义过滤器
      • 5.1 自定义GatewayFilter
      • 5.2 自定义过滤器工厂
    • 六、全局过滤器
    • 总结

引言

在微服务架构中,API网关是整个系统的入口,负责请求路由、负载均衡、认证鉴权、限流熔断等关键功能。Spring Cloud Gateway作为Spring Cloud生态中的新一代API网关,基于Spring WebFlux和Reactor构建,提供了非阻塞、响应式的API网关解决方案。相比于Zuul,Gateway具有更强的性能和更丰富的功能。本文将深入探讨Spring Cloud Gateway的核心概念、路由配置方法以及过滤器链机制,帮助开发者构建高效的微服务网关。

一、Gateway基本架构

Spring Cloud Gateway的核心架构包括路由(Route)、断言(Predicate)和过滤器(Filter)三大组件。路由是网关的基本单元,包含目标URI、断言集合和过滤器集合。断言用于判断请求是否满足某种条件,满足条件的请求会被路由到指定服务。过滤器则用于对请求和响应进行修改,实现各种横切功能。

/*** Gateway的基本工作流程:* 1. 客户端发送请求到Gateway* 2. Gateway的HandlerMapping组件找到与请求匹配的路由* 3. 请求经过一系列过滤器的处理* 4. 到达目标服务并获取响应* 5. 响应再次经过过滤器的处理* 6. 最终返回给客户端*/
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}
}

Gateway的核心依赖:

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

二、路由配置方式

Spring Cloud Gateway提供了两种路由配置方式:配置文件方式和Java代码方式。开发者可以根据实际需求选择适合的配置方式。

2.1 配置文件方式

通过application.yml文件可以方便地配置路由规则,这种方式简单直观,适合大多数场景:

spring:cloud:gateway:routes:- id: user-service-route            # 路由ID,需保持唯一uri: lb://user-service            # 目标URI,lb表示使用负载均衡predicates:                        # 断言条件,满足条件的请求会被路由- Path=/api/users/**            # 路径匹配断言- Method=GET,POST               # HTTP方法匹配断言- Header=X-Request-Id, \d+      # 请求头匹配断言filters:                          # 过滤器- StripPrefix=1                 # 去除路径前缀- AddRequestHeader=X-Gateway-Timestamp, ${now}  # 添加请求头- id: order-service-routeuri: lb://order-servicepredicates:- Path=/api/orders/**- Between=2022-01-01T00:00:00+08:00[Asia/Shanghai],2023-12-31T23:59:59+08:00[Asia/Shanghai]  # 时间范围断言filters:- StripPrefix=1- name: RequestRateLimiter      # 限流过滤器args:redis-rate-limiter.replenishRate: 10  # 令牌桶填充速率redis-rate-limiter.burstCapacity: 20   # 令牌桶容量key-resolver: "#{@userKeyResolver}"    # 限流键解析器

2.2 Java代码方式

使用Java代码配置路由提供了更灵活的编程能力,可以根据条件动态生成路由规则:

/*** 使用Java代码配置路由*/
@Configuration
public class RouteConfig {@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder builder) {return builder.routes()// 用户服务路由.route("user-service-route", r -> r.path("/api/users/**").and().method("GET", "POST").filters(f -> f.stripPrefix(1).addRequestHeader("X-Gateway-Timestamp", String.valueOf(System.currentTimeMillis())).requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter()).setKeyResolver(userKeyResolver()))).uri("lb://user-service"))// 订单服务路由.route("order-service-route", r -> r.path("/api/orders/**").filters(f -> f.stripPrefix(1).retry(retryConfig -> retryConfig.setRetries(3).setStatuses(HttpStatus.INTERNAL_SERVER_ERROR))).uri("lb://order-service"))// 重定向路由.route("redirect-route", r -> r.path("/redirect/**").filters(f -> f.redirect(302, "https://www.example.com")).uri("no://op")).build();}/*** Redis限流器*/@Beanpublic RedisRateLimiter redisRateLimiter() {return new RedisRateLimiter(10, 20);}/*** 限流键解析器,基于用户ID*/@Beanpublic KeyResolver userKeyResolver() {return exchange -> {String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");if (userId == null) {userId = "anonymous";}return Mono.just(userId);};}
}

三、内置断言工厂

Spring Cloud Gateway提供了多种内置断言工厂,用于根据不同条件匹配路由。了解这些断言工厂的用法可以帮助开发者实现精细的路由控制。

常用的断言工厂包括:

  1. Path断言工厂:根据请求路径匹配路由
  2. Method断言工厂:根据HTTP方法匹配路由
  3. Header断言工厂:根据请求头匹配路由
  4. Query断言工厂:根据查询参数匹配路由
  5. Cookie断言工厂:根据Cookie匹配路由
  6. Host断言工厂:根据主机名匹配路由
  7. Between断言工厂:根据时间范围匹配路由
  8. Weight断言工厂:按比例将请求路由到不同服务
# 断言工厂使用示例
spring:cloud:gateway:routes:- id: complex-routeuri: lb://example-servicepredicates:- Path=/api/{segment}/{id}      # 路径变量- Method=GET- Query=version, v[1-3]         # 查询参数正则匹配- Header=X-API-Version, \d+     # 请求头正则匹配- Cookie=session, \w+           # Cookie正则匹配- Host=**.example.org           # 主机名通配符匹配- Weight=group1, 8              # 按8:2的比例路由

四、内置过滤器工厂

Gateway的过滤器是实现网关功能的核心组件,可以对请求和响应进行各种处理。Gateway提供了丰富的内置过滤器工厂,满足常见的网关功能需求。

4.1 请求路径相关过滤器

filters:# 去除前缀- StripPrefix=1# 添加前缀- PrefixPath=/api# 路径重写- RewritePath=/api/(?<segment>.*), /$\{segment}# 设置路径变量- SetPath=/v2/{segment}

4.2 请求和响应头过滤器

filters:# 添加请求头- AddRequestHeader=X-Request-Id, ${requestId}# 添加响应头- AddResponseHeader=X-Response-Time, ${responseTime}# 移除请求头- RemoveRequestHeader=X-Unwanted-Header# 移除响应头- RemoveResponseHeader=X-Internal-Header# 修改请求头- MapRequestHeader=X-Old-Header, X-New-Header

4.3 功能性过滤器

filters:# 重定向- RedirectTo=302, https://example.org# 请求大小限制- RequestSize=5MB# 重试- name: Retryargs:retries: 3statuses: INTERNAL_SERVER_ERRORmethods: GET,POST# 熔断- name: CircuitBreakerargs:name: defaultCircuitBreakerfallbackUri: forward:/fallback# 限流- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 10redis-rate-limiter.burstCapacity: 20key-resolver: "#{@userKeyResolver}"

五、自定义过滤器

除了使用内置过滤器外,Gateway还支持自定义过滤器,以满足特定业务需求。自定义过滤器有两种方式:实现GatewayFilter接口或继承AbstractGatewayFilterFactory类。

5.1 自定义GatewayFilter

/*** 自定义GatewayFilter* 记录请求处理时间*/
@Component
public class RequestTimeFilter implements GatewayFilter, Ordered {private static final Logger log = LoggerFactory.getLogger(RequestTimeFilter.class);@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {exchange.getAttributes().put("requestTimeBegin", System.currentTimeMillis());return chain.filter(exchange).then(Mono.fromRunnable(() -> {Long startTime = exchange.getAttribute("requestTimeBegin");if (startTime != null) {Long endTime = System.currentTimeMillis();log.info("Request {} processed in {} ms", exchange.getRequest().getURI().getPath(), endTime - startTime);}}));}@Overridepublic int getOrder() {return Ordered.LOWEST_PRECEDENCE;}
}/*** 在路由配置中使用自定义过滤器*/
@Configuration
public class CustomFilterConfig {@Beanpublic RouteLocator customFilterRoute(RouteLocatorBuilder builder, RequestTimeFilter timeFilter) {return builder.routes().route("custom-filter-route", r -> r.path("/api/custom/**").filters(f -> f.filter(timeFilter)).uri("lb://custom-service")).build();}
}

5.2 自定义过滤器工厂

/*** 自定义过滤器工厂* 添加请求日志*/
@Component
public class RequestLogGatewayFilterFactory extends AbstractGatewayFilterFactory<RequestLogGatewayFilterFactory.Config> {private static final Logger log = LoggerFactory.getLogger(RequestLogGatewayFilterFactory.class);public RequestLogGatewayFilterFactory() {super(Config.class);}@Overridepublic GatewayFilter apply(Config config) {return (exchange, chain) -> {ServerHttpRequest request = exchange.getRequest();// 记录请求信息if (config.isLogHeaders()) {log.info("Request headers: {}", request.getHeaders());}log.info("Request method: {}, path: {}, client: {}", request.getMethod(), request.getURI().getPath(),request.getRemoteAddress());return chain.filter(exchange);};}/*** 过滤器配置类*/public static class Config {private boolean logHeaders;public boolean isLogHeaders() {return logHeaders;}public void setLogHeaders(boolean logHeaders) {this.logHeaders = logHeaders;}}@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList("logHeaders");}
}

在配置文件中使用自定义过滤器工厂:

spring:cloud:gateway:routes:- id: custom-filter-factory-routeuri: lb://example-servicepredicates:- Path=/api/example/**filters:- RequestLog=true  # 使用自定义过滤器工厂,参数为logHeaders

六、全局过滤器

全局过滤器会应用到所有路由上,适合实现通用功能,如认证、监控、日志等。实现GlobalFilter接口可以创建全局过滤器。

/*** 全局认证过滤器* 对所有请求进行JWT认证*/
@Component
public class AuthenticationFilter implements GlobalFilter, Ordered {@Autowiredprivate JwtTokenValidator tokenValidator;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();// 跳过公开APIif (isPublicApi(request.getURI().getPath())) {return chain.filter(exchange);}// 获取tokenString token = getTokenFromRequest(request);if (token == null) {return unauthorized(exchange);}// 验证tokenif (!tokenValidator.validate(token)) {return unauthorized(exchange);}// 解析用户信息并放入请求头String userId = tokenValidator.getUserId(token);ServerHttpRequest mutatedRequest = request.mutate().header("X-User-Id", userId).build();return chain.filter(exchange.mutate().request(mutatedRequest).build());}private boolean isPublicApi(String path) {return path.startsWith("/api/public/") || path.startsWith("/auth/");}private String getTokenFromRequest(ServerHttpRequest request) {List<String> authHeaders = request.getHeaders().get("Authorization");if (authHeaders != null && !authHeaders.isEmpty()) {String authHeader = authHeaders.get(0);if (authHeader.startsWith("Bearer ")) {return authHeader.substring(7);}}return null;}private Mono<Void> unauthorized(ServerWebExchange exchange) {ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}@Overridepublic int getOrder() {return -100;  // 确保认证过滤器先执行}
}

总结

Spring Cloud Gateway作为新一代API网关,凭借其基于WebFlux的响应式特性,提供了高性能的请求路由和处理能力。本文介绍了Gateway的基本架构、路由配置方法、断言工厂使用、过滤器链机制以及自定义过滤器的实现方式。通过合理配置路由和过滤器,可以实现请求转发、负载均衡、认证鉴权、限流熔断等微服务网关的核心功能。

在实际应用中,开发者可以根据具体需求选择配置文件或Java代码方式定义路由,组合使用内置断言和过滤器,或实现自定义过滤器和全局过滤器,构建功能完备的API网关。随着微服务架构的不断发展,Gateway的非阻塞特性和丰富的功能使其成为构建现代微服务网关的理想选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/36013.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

咖啡点单小程序毕业设计(JAVA+SpringBoot+微信小程序+完整源码+论文)

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着社会的快速发展和…

Excel(函数进阶篇):Vlookup函数进阶、TAKE嵌套SORE函数、SUBTOTAL函数、INDIRECT函数

目录 Vlookup函数返回多列结果Vlookup函数多条件匹配Vlookup函数部分匹配TAKE函数嵌套SORT函数&#xff0c;提取排序数据SUBTOTAL函数&#xff1a;制作动态报表SUBTOTAL函数&#xff1a;创建连续编号INDIRECT函数Vlookup跨多表抓取数据INDIRECT函数常见跨表的错误Vloopup函数联…

大模型 VS 传统算法:人工智能时代的“新老对话“

大模型 VS 传统算法&#xff1a;人工智能时代的"新老对话" 在AlphaGo击败李世石、ChatGPT掀起全民AI热潮的今天&#xff0c;人们往往将"大模型"与"算法"混为一谈。但当我们深入技术内核时会发现&#xff0c;这二者恰似人工智能发展的两个平行宇…

【蓝桥杯每日一题】3.17

&#x1f3dd;️专栏&#xff1a; 【蓝桥杯备篇】 &#x1f305;主页&#xff1a; f狐o狸x 他们说内存泄漏是bug&#xff0c;我说这是系统在逼我进化成SSR级程序员 OK来吧&#xff0c;不多废话&#xff0c;今天来点有难度的&#xff1a;二进制枚举 二进制枚举&#xff0c;就是…

Matlab 汽车振动多自由度非线性悬挂系统和参数研究

1、内容简介 略 Matlab 169-汽车振动多自由度非线性悬挂系统和参数研究 可以交流、咨询、答疑 2、内容说明 略 第二章 汽车模型建立 2.1 汽车悬架系统概述 2.1.1 悬架系统的结构和功能 2.1.2 悬架分类 2.2 四分之一车辆模型 对于车辆动力学&#xff0c;一般都是研究其悬…

hackmyvm-Smol

信息收集 ┌──(root㉿kali)-[/home/kali] └─# arp-scan -I eth1 192.168.56.0/24 Interface: eth1, type: EN10MB, MAC: 00:0c:29:34:da:f5, IPv4: 192.168.56.103 WARNING: Cannot open MAC/Vendor file ieee-oui.txt: Permission denied WARNING: Cannot open MAC/Vendo…

深度学习项目--基于DenseNet网络的“乳腺癌图像识别”,准确率90%+,pytorch复现

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 如果说最经典的神经网络&#xff0c;ResNet肯定是一个&#xff0c;从ResNet发布后&#xff0c;很多人做了修改&#xff0c;denseNet网络无疑是最成功的…

基于x11vnc的ubuntu远程桌面

1、安装VNC服务 sudo apt install x11vnc -y2、创建连接密码 sudo x11vnc -storepasswd3、安装lightdm服务 x11vnc 在 默认的 GDM3 中不起作用&#xff0c;因此需要使用 lightdm 桌面管理环境 sudo apt install lightdm -y切换至lightdm&#xff0c;上一步已经切换则跳过该…

Git 常用命令完全指南:从入门到高效协作

文章需要结构清晰&#xff0c;涵盖从入门到进阶的常用命令&#xff0c;结合实例和注意事项&#xff0c;帮助用户快速掌握Git的核心功能&#xff0c;并应用到实际项目中 一、仓库初始化与基础操作 1. 创建与克隆仓库 # 初始化本地仓库 git init# 克隆远程仓库&#xff08;SSH方…

【运维自动化-标准运维】如何实现一个最简单的流程编排

流程编排是标准运维最核心的功能&#xff0c;通过将不同功能的原子插件在画布上可视化的拖拽编排&#xff0c;可以实现各种不同场景的跨系统工作流。标准运维流程 根据实际运维操作场景梳理出来的操作步骤&#xff0c;通过不同的流转逻辑&#xff08;并行、分支、条件并行&…

【DeepSeek】HTML Api调用(支持V3和 R1,多轮对话、流式输出、对话保存、markdown格式支持)

文章目录 一、项目结构二、功能支持三、使用方法四、待改进五、参数优化 ☘️ 项目地址&#xff1a;https://github.com/CQUPTLei/DeepSeek_HTML/tree/master 对话截图&#xff1a; 一、项目结构 C:\USERS\14134\DESKTOP\DEEPSEEK │ .gitignore │ DeepSeek.html # 所…

烽火HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包及注意点说明

之前发布过这个固件包&#xff0c;关于烽火HG680-KA&#xff0f;HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包详细说明一下&#xff0c;汇总总结一些常遇到的情况&#xff0c;这次固件会分开发布&#xff0c;以免混淆。 上一个帖子地址&#xff1a;烽火HG680-KA&#xff0…

蓝桥杯备赛(基础语法4)

冒泡排序 冒泡排序的思想 冒泡排序的思想是每次将最大的一下一下运到最右边&#xff0c;然后将最右边这个确定下来。再来确定第二大的&#xff0c;再确定第三大的... 对于数组 a [ ] ,具体的来说&#xff0c;每次确定操作就是从左往右扫描&#xff0c;如果 a [ i ] > a [ …

【算法】力扣 713题:乘积小于 K 的子数组之深入思考

文章目录 前言题目&#xff1a;乘积小于 K 的子数组参考思路方法一&#xff1a;滑动窗口方法二&#xff1a;二分查找 参考题解方法一&#xff1a;滑动窗口解法方法二&#xff1a;二分查找解法 深入思考浮点精度&#xff1f;right - left 1&#xff1f;二分法&#xff1f;哈希优…

超声重建,3D重建 超声三维重建,三维可视化平台 UR 3D Reconstruction

1. 超声波3D重建技术的实现方法与算法 技术概述 3D超声重建是一种基于2D超声图像生成3D体积数据的技术&#xff0c;广泛应用于医学影像领域。通过重建和可视化三维结构&#xff0c;3D超声能够显著提高诊断精度和效率&#xff0c;同时减少医生的脑力负担。本技术文档将详细阐述…

Docker 部署 Graylog 日志管理系统

Docker 部署 Graylog 日志管理系统 前言一、准备工作二、Docker Compose 配置三、启动 Graylog 服务四、访问 Graylog Web 界面总结 前言 Graylog 是一个开源的日志管理平台&#xff0c;专为实时日志收集、分析和可视化设计。它支持强大的搜索功能&#xff0c;并且与 Elastics…

【图论】并查集的学习和使用

目录 并查集是什么&#xff1f; 举个例子 组成 父亲数组&#xff1a; find函数&#xff1a; union函数&#xff1a; 代码实现&#xff1a; fa[] 初始化code: find code&#xff1a; 递归实现: 非递归实现: union code : 画图模拟&#xff1a; 路径压缩&#xff1a…

FPGA-流水灯

Quartus中使用Verilog实现 根据之前所学内容&#xff0c;打开Quartus 软件&#xff0c;新建FPGA项目文件&#xff0c;建立好空项目过后&#xff0c;选择Verilog HDL File&#xff0c;因为我们要使用Verilog代码实现仿真。 详细操作可参考往期博客&#xff1a; FPGA 实验报告&a…

React19源码系列之createRoot的执行流程是怎么的?

2024年12月5日&#xff0c;react发布了react19版本。后面一段时间都将学习它的源码&#xff0c;并着手记录。 react官网&#xff1a;react19新特性 https://react.dev/blog/2024/12/05/react-19 在用vite创建react项目的使用&#xff0c;main.tsx主文件都会有以下代码。 //i…

全网首创/纯Qt/C++实现国标GB28181服务/实时视频/云台控制/预置位/录像回放和下载/事件订阅/语音对讲

一、前言说明 用纯Qt来实现这个GB28181的想法很久了&#xff0c;具体可以追溯到2014年&#xff0c;一晃十年都过去了&#xff0c;总算是整体的框架和逻辑都打通了&#xff0c;总归还是杂七杂八的事情多&#xff0c;无法静下心来研究具体的协议&#xff0c;最开始初步了解协议后…