利用Spring Cloud Gateway Predicate优化微服务路由策略

利用Spring Cloud Gateway Predicate优化微服务路由策略

一、Predicate简介

Spring Cloud Gateway 是 Spring 生态系统中用于构建 API 网关的框架,它基于 Project Reactor 和 Netty 构建,旨在提供一种高效且灵活的方式来处理 HTTP 请求和响应。

Spring Cloud Gateway 的路由配置中,predicates​(断言)用于定义哪些请求应该匹配特定的路由规则。

断言是Gateway在进行路由时,根据具体的请求信息如请求路径、请求方法、请求参数等进行匹配的规则。当一个请求的信息符合断言设置的条件时,Gateway就会将该请求路由到对应的服务上。

959dc8c278fb589e1ed43742b6ca53d41

根据源码可以看到Spring cloud gateway 的内置断言,可以看到核心10个内置Predicate

image

在 Spring Cloud Gateway 的配置中,Predicate​ 通常通过 predicates​ 字段定义,配合路由配置一起使用。它可以基于以下方面来进行请求匹配:

  • 路径匹配(Path)
  • 请求方法匹配(Method)
  • 请求头匹配(Header)
  • 请求参数匹配(Query Param)
  • IP 地址匹配(IP)
  • 主机名匹配(Host)
  • 负载均衡支持(lb://)

Spring Cloud Gateway除了提供一系列内置的断言工厂,同时也支持自定义断言。

二、常见 Predicate 类型

image

2.1 Path Predicate

Path Predicate 用于根据请求的路径进行匹配。

predicates:
  - Path=/api/**  # 匹配以 /api/ 开头的请求路径
  • 示例Path=/api/**​ 匹配请求路径以 /api/​ 开头的所有请求,包括 /api/v1/users​、/api/v2/orders​ 等。

  • 通配符

    • **​ 表示匹配任意路径段。
    • *​ 表示匹配单个路径段。

示例

spring:
  application:
    name: spring-cloud-gateway-sample
  cloud:
    gateway:
      routes:
        - id: blog
          uri: http://blog.abc.com
          predicates:
            # 匹配路径转发
            - Path=/api-boot-datasource-switch.html
# 端口号
server:
  port: 9090

在上面的配置中,当访问http://localhost:9090/api-boot-datasource-switch.html​时就会被自动转发到http://blog.abc.com/api-boot-datasource-switch.html​,这里要注意完全匹配Path​的值时才会进行路由转发

2.2 Method Predicate

Method Predicate 用于根据请求的方法类型(GET、POST、PUT 等)进行匹配。

predicates:
  - Method=GET  # 仅匹配 GET 请求
  • 示例Method=POST​ 只会匹配 HTTP POST 方法的请求。

2.3 Header Predicate

Header Predicate 用于根据请求中的某些头信息进行匹配。

predicates:
  - Header=Content-Type=application/json  # 匹配 Content-Type 头为 application/json 的请求
  • 示例Header=X-Custom-Header=foo​ 匹配请求头中 X-Custom-Header​ 值为 foo​ 的请求。

2.4 Query Param Predicate

Query Param Predicate 用于根据请求 URL 中的查询参数进行匹配。

predicates:
  - Query=type=admin  # 匹配 URL 中包含 ?type=admin 的请求
  • 示例Query=user=admin​ 匹配 URL 中查询参数 user=admin​ 的请求,如 https://example.com?user=admin​。

2.5 Host Predicate

Host Predicate 用于根据请求的 Host​ 头进行匹配。

predicates:
  - Host=example.com  # 匹配 Host 头为 example.com 的请求
  • 示例Host=*.example.com​ 匹配 example.com​ 域名下的所有子域名,如 api.example.com​、blog.example.com​ 等。

2.6 IP Predicate

IP Predicate 用于根据请求源 IP 地址进行匹配。

predicates:
  - Ip=192.168.1.0/24  # 匹配来自 192.168.1.0/24 网段的请求
  • 示例Ip=10.0.0.0/8​ 匹配来自 10.0.0.0/8​ 网段的请求。

2.7 Accept Predicate

Accept Predicate 用于根据请求的 Accept​ 头部进行匹配。

predicates:
  - Accept=application/json  # 匹配 Accept 头为 application/json 的请求
  • 示例Accept=text/html​ 匹配 Accept​ 头为 text/html​ 的请求。

2.8 Composite Predicate

你可以将多个 Predicate 组合成一个复合条件,使用 and​、or​ 等逻辑操作符。

predicates:
  - Path=/api/** and Method=POST  # 请求路径以 /api/ 开头,且请求方法为 POST
  - Path=/api/** or Query=user=admin  # 请求路径以 /api/ 开头,或查询参数 user=admin

2.9 Cookie

  • 用途:匹配请求中的 Cookie。

  • 示例

    predicates:
      - Cookie=chocolate, choco\.value
    

    匹配名为 chocolate​ 且值符合正则表达式 choco\.value​ 的 Cookie。

2.10 After 和 Before

  • 用途:基于时间戳匹配请求。

  • 示例

    predicates:
      - After=2024-01-01T00:00:00+08:00[Asia/Shanghai]
    

    匹配在指定日期之后发出的请求。

    predicates:
      - Before=2024-01-01T00:00:00+08:00[Asia/Shanghai]
    

    匹配在指定日期之前发出的请求。

2.11 Between

  • 用途:结合 After​ 和 Before​,匹配某一时间段内的请求。

  • 示例

    predicates:
      - Between=2024-01-01T00:00:00+08:00[Asia/Shanghai],2024-01-31T23:59:59+08:00[Asia/Shanghai]
    

2.12 RemoteAddr

  • 用途:匹配客户端 IP 地址或 CIDR 块。

  • 示例

    predicates:
      - RemoteAddr=192.168.1.1/24
    

    匹配来自特定网段的请求。

三、Predicate 的组合

Spring Cloud Gateway 允许你通过逻辑运算符(and​、or​)组合多个 Predicate,定义更复杂的路由匹配规则。你可以组合不同的 Predicate 来匹配路径、方法、头部、参数等。

示例 1:匹配路径为 /api/**​ 且请求方法为 POST 的请求:

predicates:
  - Path=/api/** and Method=POST

示例 2:匹配路径为 /api/**​ 或者查询参数 user=admin​ 的请求:

predicates:
  - Path=/api/** or Query=user=admin

示例 3:使用多个 and​ 来组合复杂的匹配条件:

predicates:
  - Path=/api/** and Method=GET and Header=Authorization=Bearer

这表示只有当请求路径为 /api/**​ 且请求方法为 GET​,且请求头中包含 Authorization: Bearer​ 时,才会匹配此路由。

常用组合示例

1) 匹配 GET 请求并带有 Authorization

predicates:
  - Method=GET and Header=Authorization=Bearer

2) 匹配特定域名和查询参数

predicates:
  - Host=api.example.com and Query=type=admin

3) 匹配路径和方法的组合

predicates:
  - Path=/products/** and Method=GET

4) 路径匹配和 IP 匹配

predicates:
  - Path=/api/** and Ip=192.168.1.0/24

四、自定义断言

除了使用内置的断言工厂外,还可以通过实现自己的 GatewayFilterFactory​ 来创建自定义断言。这使得你可以根据业务逻辑添加更加复杂的匹配条件。

示例:自定义断言

假设我们想要创建一个名为 Custom​ 的自定义断言,它可以根据请求体中的 JSON 字段进行匹配。

import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import reactor.core.publisher.Mono;

public class CustomPredicateFactory extends AbstractRoutePredicateFactory<CustomPredicateFactory.Config> {

    public CustomPredicateFactory() {
        super(Config.class);
    }

    @Override
    public Mono<Boolean> applyAsync(Config config, ServerHttpRequest request) {
        // 实现具体的匹配逻辑
        return Mono.just(request.getHeaders().containsKey("Custom-Header"));
    }

    public static class Config {
        private String key;

        // Getters and setters
    }
}

然后在配置文件中引用这个自定义断言:

predicates:
  - name: Custom
    args:
      key: value

总结

  • Predicate​ 是 Spring Cloud Gateway 中定义路由匹配条件的核心组件,通过多个 Predicate​ 条件,你可以灵活地匹配请求。
  • 支持多种常见的匹配方式,包括路径、方法、头部、查询参数、IP、主机等。
  • 可以组合多个 Predicate​ 以构建复杂的路由规则。
  • 支持逻辑组合(如 and​、or​)来满足不同的路由需求。

通过灵活使用 Predicate​,你可以对不同的请求进行精准路由控制,从而实现高效的请求管理和流量分发。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java基础面试题035】什么是Java泛型的上下界限定符?

回答重点 Java泛型的上下界限定符用于对泛型类型参数进行范围限制&#xff0c;主要有上界限定符和下届限定符。 1&#xff09;上界限定符 (? extends T)&#xff1a; 定义&#xff1a;通配符?的类型必须是T或者T的子类&#xff0c;保证集合元素一定是T或者T的子类作用&…

用套接字的UDP,TCP知道什么是HTTP吗?

文章目录 UDP和TCP七层网络架构Omnipeek抓包分析举例图片备注code参考code HTTP协议的构成 UDP和TCP UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09; 和 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09; 是…

Apache Log4j漏洞复现

所用环境 宝塔云服务器 log4j2 是Apache的⼀个java日志框架&#xff0c;我们借助它进行日志相关操作管理&#xff0c;然而在2021年末log4j2爆出了远程代码执行漏洞&#xff0c;属于严重等级的漏洞。 apache log4j通过定义每⼀条日志信息的级别能够更加细致地控制日志⽣成地过…

苍穹外卖-day05redis 缓存的学习

苍穹外卖-day05 课程内容 Redis入门Redis数据类型Redis常用命令在Java中操作Redis店铺营业状态设置 学习目标 了解Redis的作用和安装过程 掌握Redis常用的数据类型 掌握Redis常用命令的使用 能够使用Spring Data Redis相关API操作Redis 能够开发店铺营业状态功能代码 功能实…

CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究

论文标题 An Empirical Study of Scaling Law for OCR OCR 缩放定律的实证研究 论文链接&#xff1a; An Empirical Study of Scaling Law for OCR论文下载 论文作者 Miao Rang, Zhenni Bi, Chuanjian Liu, Yunhe Wang, Kai Han 内容简介 本论文在光学字符识别&#xf…

PTA数据结构题目:链表操作集合

寻找结点 插入结点 错误分析 while (prev ! NULL && prev->Next ! P) 为什么我写成 while (prev->Next ! P && prev ! NULL) 的时候会发生段错误&#xff0c;这两种写法逻辑上不是一样的吗&#xff1f; 野指针 逻辑顺序导致的潜在风险 在 C 语言中&am…

路由器做WPAD、VPN、透明代理中之间一个

本文章将采用家中TP-Link路由器 路由器进行配置DNS DNS理解知识本文DNS描述参考&#xff1a;网络安全基础知识&中间件简单介绍_计算机网络中间件-CSDN博客 TP LINK未知的错误&#xff0c;错误编号&#xff1a;-22025 TP-LINK 认证界面地址&#xff1a;https://realnam…

Java 小白入门必备知识点

11.我们发现现在有两个x&#xff0c;一个是成员变量&#xff0c;一个是局部变量&#xff0c;在sum方法中为了区分两个s&#xff0c;我们给成员变量前加上this以此来区分成员变量和局部变量 12.成员方法:在java中&#xff0c;必须通过方法才能完成对类和对象的属性操作&#xf…

gitlab代码推送

点击这个√ 修改的文件全部选上 填好提交的名称 点击commit 选取提交的 gitlab 库 点击Push

vscode添加全局宏定义

利用vscode编辑代码时&#xff0c;设置了禁用非活动区域着色后&#xff0c;在一些编译脚本中配置的宏又识别不了 遇到#ifdef包住的代码就会变暗色&#xff0c;想查看代码不是很方便。如下图&#xff1a; 一 解决&#xff1a; 在vscode中添加全局宏定义。 二 步骤&#xff1a…

【电路设计】LDO旁路电容的选择

本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时&#xff0c;也能帮助其他需要参考的朋友。如有谬误&#xff0c;欢迎大家进行指正。 一、引言 虽然人们普遍认为电容是解决噪声相关问题的灵丹妙药&#xff0c;但是电容的价值并不仅限于此。设计人员常常只想到…

生产看板管理系统涵盖哪些方面

嘿&#xff0c;各位搞生产管理的朋友&#xff0c;肯定都碰到过些麻烦事儿吧。我就寻思着&#xff0c;能不能弄出个 “明明白白” 的工作场地呢&#xff1f;让员工和管理人员都能随时查查生产进度&#xff0c;一发现生产里有啥问题就能立马知道。 生产进度不好追踪生产过程不清…

Python|Pyppeteer实现全自动化触发reCaptcha验证码(28)

前言 本文是该专栏的第28篇,结合优质项目案例持续分享Pyppeteer的干货知识,记得关注。 针对近期多位同学,询问如何自动化触发“reCaptcha验证码”的问题。笔者在本文,将结合实战项目完整代码进行详细说明。 对“reCaptcha验证码”感兴趣的同学,千万别错过。 废话不多说,…

SpringBoot介绍以及基本注解和应用

一.Spring Boot 简介&#xff08;脚手架&#xff09; 1.简介 简化Spring应用开发的一个框架&#xff1b; 整个Spring技术栈的一个大整合&#xff1b; J2EE开发的一站式解决方案&#xff1b; 优点&#xff1a;快速创建独立运行的spring项目以及与主流框架集成 使用嵌入式的S…

Niushop开源商城(漏洞复现)

文件上传漏洞 注册一个账号后登录 在个人中心修改个人头像 选择我们的图片马 #一句话(不想麻烦的选择一句话也可以) <?php eval($_POST["cmd"]);?> #生成h.php文件 <?php fputs(fopen(h.php,w),<?php eval($_POST["cmd"]);?>); ?&…

容器技术所涉及Linux内核关键技术

容器技术所涉及Linux内核关键技术 一、容器技术前世今生 1.1 1979年 — chroot 容器技术的概念可以追溯到1979年的UNIX chroot。它是一套“UNIX操作系统”系统&#xff0c;旨在将其root目录及其它子目录变更至文件系统内的新位置&#xff0c;且只接受特定进程的访问。这项功…

攻防世界 web view_source

开启场景 右键用不了就 F12 试试&#xff0c;然后看见了 flag cyberpeace{62caa734bc21cc4f9dc97ece9a882cd3}

如何保护你的 iOS 应用免受逆向工程攻击

逆向工程是分析和解构软件以理解其工作原理的过程。针对 iOS 应用&#xff0c;逆向工程通常涉及分析已编译的二进制文件&#xff08;机器可读的代码&#xff09;&#xff0c;并将其转化为更容易被人类理解的形式。这使得攻击者能够检查应用的逻辑、理解数据处理的方式&#xff…

C++进阶(二)--面向对象--继承

目录 一、继承的概念及定义 1.继承的概念 2.继承的定义 定义格式 继承方式和访问限定符 继承基类成员访问⽅式的变化 3.继承类模板 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派⽣类的默认成员函数 五、继承与友元 六、继承与静态成员 七、多继承及其…

STM32串口第一次接收数据时第一个字节丢失的问题

解决方法&#xff1a;开启中断之前&#xff0c;先清除标志位【1】。 串口清除标志位&#xff1a; __HAL_UART_CLEAR_PEFLAG(&huart1); HAL_UART_Receive_IT(&huart1,&RxUart, 1); 定时器清除标志位&#xff1a; __HAL_TIM_CLEAR_FLAG(&htim3,TIM_FLAG_UPDATE);…