SpringColoud GateWay 核心组件

news2024/11/26 0:41:24

优质博文:IT-BLOG-CN

【1】Route路由: Gateway的基本构建模块,它由ID、目标URL、断言集合和过滤器集合组成。如果聚合断言结果为真,则匹配到该路由。

Route路由-动态路由实现原理: 配置变化Apollo + 服务地址实例变化NacosSpring Cloud Gateway通过RouteDefinitionLocatorRouteRefreshListener等组件实现动态路由。

先看下配置信息,方便后面原理的理解:SpringCloudGateway bootstrap.yml的配置如下:

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
    apollo:
      bootstrap:
        enabled: true
      meta: ${APOLLO_META:localhost:8080}

application.yml的配置如下:

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
apollo:
  bootstrap:
    namespaces: application # 1、登录 Apollo 控制台。 2、创建一个新的配置,例如 application.yml。 3、内容就是上看配置的SpringCloud Gateway 配置的路由信息

1、RouteDefinitionLocatorSpring Cloud Gateway启动时,会通过RouteDefinitionLocatorApollo加载初始的路由定义。
2、DiscoveryClientRouteDefinitionLocator:使用Nacos进行服务发现,从Nacos获取动态路由定义。
3、RouteDefinitionRepository:加载的路由定义会存储在RouteDefinitionRepository中,供后续路由匹配使用。
4、RouteRefreshListener:监听路由定义的变化事件(如配置更新、服务实例变化等)。当监听到路由定义变化事件时,触发路由刷新操作,更新网关的路由规则,重新加载并应用新的路由配置。

GatewayHandlerMapping根据预先配置的路由信息和请求的属性(如路径、方法、头部信息等)来确定哪个路由与请求匹配。它使用谓词Predicates来进行匹配判断。

【2】Predicate断言: 这是一个Java 8 Function Predicate。输入类型是Spring Framework ServerWebExchange。允许开发人员匹配来自HTTP请求的任何内容,例如Header或参数。Predicate接受一个输入参数,返回一个布尔值结果。Spring Cloud Gateway内置了许多Predict,这些Predict的源码在org.springframework.cloud.gateway.handler.predicate包中,如果读者有兴趣可以阅读一下。现在列举各种 Predicate如下图:

在上图中,有很多类型的Predicate,比如说时间类型的 Predicated[AfterRoutePredicateFactory BeforeRoutePredicateFactory BetweenRoutePredicateFactory],当只有满足特定时间要求的请求会进入到此Predicate中,并交由Router处理;Cookie类型的CookieRoutePredicateFactory,指定的Cookie满足正则匹配,才会进入此Router。以及hostmethodpathquerparamremoteaddr类型的Predicate,每一种Predicate都会对当前的客户端请求进行判断,是否满足当前的要求,如果满足则交给当前请求处理。如果有很多个Predicate,并且一个请求满足多个Predicate,则按照配置的顺序第一个生效。

Predicate 断言配置:

server:
  port: 8080
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: gateway-service
          uri: https://www.baidu.com
          order: 0
          predicates:
            - After=2017-01-20T17:42:47.789-07:00[America/Denver]
            - Host=**.foo.org
            - Path=/headers
            - Method=GET
            - Header=X-Request-Id, \d+
            - Query=foo, ba.
            - Query=baz
            - Cookie=chocolate, ch.p

在上面的配置文件中,配置了服务的端口为8080,配置spring cloud gateway相关的配置,id标签配置的是routerid,每个router都需要一个唯一的iduri配置的是将请求路由到哪里,本案例全部路由到https://www.baidu.com

Predicates After=2017-01-20T17:42:47.789-07:00[America/Denver] 会被解析成PredicateDefinition对象name =After ,args= 2017-01-20T17:42:47.789-07:00[America/Denver]。需要注意的是PredicatesAfter这个配置,遵循契约大于配置的思想,它实际被 AfterRoutePredicateFactory这个类所处理,这个After就是指定了它的Gateway web handler类为AfterRoutePredicateFactory,同理,其他类型的Predicate也遵循这个规则。当请求的时间在这个配置的时间之后,请求会被路由到指定的URL。跟时间相关的Predicates还有 Before Route Predicate FactoryBetween Route Predicate Factory,读者可以自行查阅官方文档,再次不再演示。

Query=baz Query的值以键值对的方式进行配置,这样在请求过来时会对属性值和正则进行匹配,匹配上才会走路由。经过测试发现只要请求汇总带有baz参数即会匹配路由[localhost:8080?baz=x&id=2],不带baz参数则不会匹配。

Query=foo, ba.:这样只要当请求中包含foo属性并且参数值是以 ba开头的长度为三位的字符串才会进行匹配和路由。使用curl测试,命令行输入:curl localhost:8080?foo=bab测试可以返回页面代码,将foo的属性值改为babx再次访问就会报404,证明路由需要匹配正则表达式才会进行路由。

Header=X-Request-Id, \d+:使用curl测试,命令行输入:curl http://localhost:8080 -H "X-Request-Id:88" 则返回页面代码证明匹配成功。将参数-H "X-Request-Id:88"改为-H "X-Request-Id:spring"再次执行时返回404证明没有匹配。

【3】Filter过滤器:方案一:写死在代码中

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
        //openapi路由转发
        .route("openapi_route", p -> p.path( "/openapi/**").filters(f->f.removeRequestHeader("Expect"))
        .uri("lb://order-openapi-service"))
        .build();
}

方案二:配置文件yml

# gateway 的配置形式
 routes:
  - id: order-service #路由ID,没有规定规则但要求唯一,建议配合服务名。
    uri: lb://order-service
    predicates:
      - Path=/order/**
    filters:
      - ValidateCodeGatewayFilter

Filter过滤器:Filter按处理顺序Pre Filter / Post Filter

Filter按作用范围分为: GlobalFilter全局过滤器。GatewayFilter 指定路由的过滤器。
Filter过滤器-扩展自定义Filter Filter支持通过spi扩展。实现GatewayFilterOrdered接口。
Filter方法: 过滤器处理逻辑。getOrder:定义优先级,值越大优先级越低。

过滤器的名称只需要写前缀,过滤器命名必须是xxxGatewayFilterFactory(包括自定义)。

全局过滤器示例: 创建一个全局过滤器类,这也是一个前置过滤器,实现GlobalFilter接口:

public class TokenFilter implements GlobalFilter, Ordered {

    Logger logger=LoggerFactory.getLogger( TokenFilter.class );
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if (token == null || token.isEmpty()) {
            logger.info( "token is empty..." );
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange); // 先执行业务逻辑,在执行exchange,是前置过滤器
    }

    @Override
    public int getOrder() {
      // // 过滤器的执行顺序,值越小优先级越高
        return -100;
    }
}

自定义路由过滤器示例: 创建自定义的路由过滤器,可以实现GatewayFilter接口:

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class MyCustomFilter extends AbstractGatewayFilterFactory<MyCustomFilter.Config> {

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

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            // 前置过滤逻辑
            System.out.println("Custom Pre Filter executed");
            
            return chain.filter(exchange).then(Mono.fromRunnable(() -> { // 限制性exchange再执行过滤器业务逻辑,是后期处理器。
                // 后置过滤逻辑
                System.out.println("Custom Post Filter executed");
            }));
        };
    }

    public static class Config {
        // 配置属性
    }
}

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

spring:
  cloud:
    gateway:
      routes:
      - id: my_route
        uri: http://httpbin.org:80
        predicates:
        - Path=/get
        filters:
        - name: MyCustomFilter

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AMD XILINX 20nm器件价格上调25%

随着市场回暖&#xff0c;台积电也在调整价格策略&#xff0c;近期台积电上调了20nm的出厂价格。 据相关消息显示&#xff0c;AMD为了保障持续的供货和服务&#xff0c;也计划将20nm器件的价格统一上调25%&#xff0c;预计将于11月发布正式的涨价通知&#xff0c;并于2025年Q1开…

七,Linux基础环境搭建(CentOS7)- 安装Scala和Spark

Linux基础环境搭建&#xff08;CentOS7&#xff09;- 安装Scala和Spark 大家注意以下的环境搭建版本号&#xff0c;如果版本不匹配有可能出现问题&#xff01; 一、Scala下载及安装 Scala是一门多范式的编程语言&#xff0c;一种类似java的编程语言&#xff0c;设计初衷是实现…

基于Java+SpringBoot+Vue的宠物咖啡馆平台的设计与实现

基于JavaSpringBootVue的宠物咖啡馆平台的设计与实现 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#…

ubuntu编译kaldi和vosk

文章目录 前言一、开源框架的选取二、kaldi编译三、编译vosk方案一方案二 前言 由于工作需要语音识别的功能&#xff0c;环境是在linux arm版上&#xff0c;所以想先在ubuntu上跑起来看一看&#xff0c;就找了一下语音识别的开源框架&#xff0c;选中了vosk这个开源库&#xf…

微软:全球每天网络攻击超6亿次

《2024年微软数字防御报告》揭示了一个复杂的全球网络安全格局&#xff0c;每天发生超过6亿次网络攻击。报告强调了勒索软件、网络钓鱼和身份泄露事件的增加&#xff0c;以及网络犯罪团伙和国家行为者之间的合作。它强调了人工智能在攻击和防御中的重要作用&#xff0c;敦促组织…

基于SpringBoot的“高校校园点餐系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“高校校园点餐系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台首页功能界面图 用户注册、登录界面图 我…

Java中的程序、进程、线程、并行和并发

程序 一段静态的代码进程 ① 正在内存中运行的“程序” ② 是操作系统调度和分配资源的最小单位线程 ① 进程可进一步细化为线程&#xff0c;是程序内部的一条执行路径&#xff0c;一个进程中至少有一个线程 ② 线程是CPU调度和执行的最小单位 ③ 多个线程共享相同的内存单元&a…

用docker Desktop 下载使用thingsboard/tb-gateway

1、因为正常的docker pull thingsboard/tb-gateway 国内不行了&#xff0c;所以需要其它工具来下载 2、在win下用powershell管理员下运行 docker search thingsboard/tb-gateway 可以访问到了 docker pull thingsboard/tb-gateway就可以下载了 3、docker Desktop就可以看到…

EasyExcel_动态表头的导入导出

文章目录 前言一、EasyExcel二、使用步骤1.引入jar包2.数据准备2.1 数据库 3.方法实例3.1 无实体的导入3.1.1 Controller3.1.2 Service3.1.3 Listener3.1.4 Utils3.1.5 无实体导入数据返回说明 3.2 无实体的导出3.2.1 无实体导出数据(这里只贴出关键代码,Service代码处理)3.2.2…

凸优化学习

认为学习凸优化理论比较合适的路径是&#xff1a; 学习/复习线性代数和&#xff08;少量&#xff09;高等数学的知识。 实际上&#xff0c;凸优化理论综合使用了线性代数和微积分的相关知识&#xff0c;比如方向导数&#xff0c;雅克比矩阵&#xff0c;海森矩阵&#xff0c;KKT…

大数据-189 Elasticsearch - ELK 日志分析实战 - 环境配置启动 Nginx、ZK、Kafka、ES、Kibana

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

写出Windows操作系统内核的程序员,70多岁,还去办公室敲代码

大家好&#xff0c;我是二哥呀。 微软前 CEO 鲍尔默曾说过一句言简意赅的话&#xff1a;“没有 Dave&#xff0c;就没有今天的微软”。 可见 Dave 在微软的分量。Dave 的全名叫 Dave Cutler&#xff0c;微软的超级程序员&#xff0c;Windows NT 操作系统内核的缔造者&#xf…

【Java】ArrayList相关操作及其案例

ArrayList相当于集合&#xff0c;作为一种容器存储数据&#xff0c;与数组类似。不同的是&#xff0c;ArrayList中长度可变&#xff0c;而数组长度不可变。 ArrayList相关API 构造器 public ArrayList() 创建一个空的集合对象 ArrayList<String>arrnew ArrayList<>…

RHCE【web服务器】

目录 一、web服务器简介 1、什么是www 2、网址及HTTP简介 3、http协议请求的工作过程&#xff1a; 二、web服务器的类型 1、仅提供用户浏览的单向静态网页 2、提供用户互动接口的动态网站 三、web服务器基本配置 四、虚拟主机配置实战 1、搭建静态网站--基于http协议…

草地杂草数据集野外草地数据集田间野草数据集YOLO格式VOC格式目标检测计算机视觉数据集

一、数据集概述 数据集名称&#xff1a;杂草图像数据集 数据集是一个包含野草种类的集合&#xff0c;其中每种野草都有详细的特征描述和标记。这些数据可以包括野草的图片、生长习性、叶片形状、颜色等特征。 1.1可能应用的领域 农业领域: 农业专家和农民可以利用这一数据集来…

Spring Boot:植物健康监测的智能先锋

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了植物健康系统的开发全过程。通过分析植物健康系统管理的不足&#xff0c;创建了一个计算机管理植物健康系统的方案。文章介绍了植物健康系统的系统分析部分&…

VScode分文件编写C++报错 | 如何进行VScode分文件编写C++ | 不懂也能轻松解决版

分文件编写遇到的问题 分文件编写例子如下所示&#xff1a; 但是直接使用 Run Code 或者 调试C/C文件 会报错如下&#xff1a; 正在执行任务: C/C: g.exe 生成活动文件 正在启动生成… cmd /c chcp 65001>nul && D:\Librarys\mingw64\bin\g.exe -fdiagnostics-col…

RabbitMQ常见问题持续汇总

文章目录 消息分发不公平分发限流-basic.qos主要功能使用场景示例代码 消费者默认concurrency数量prefetch和concurrency结合&#xff1f; spring.rabbitmq.template.retry.enabledtrue和spring.rabbitmq.listener.simple.retry.enabledtrue有什么区别1. spring.rabbitmq.templ…

中药大数据(二)中药方剂表设计与导入

中药大数据&#xff08;二&#xff09;中药方剂表设计与导入 最近在做一个中药大数据的单子&#xff0c;已经爬取到了中药和方剂的数据&#xff0c;现在根据爬取到的数据设计数据库和导入neo4j形成知识图谱。 1 中药方剂数据表设计 爬取到的字段有 方剂名 title 处方 presc…

自动化部署-01-jenkins安装

文章目录 前言一、下载安装二、启动三、问题3.1 jdk版本问题3.2 端口冲突3.3 系统字体配置问题 四、再次启动五、配置jenkins5.1 解锁5.2 安装插件5.3 创建管理员用户5.4 实例配置5.5 开始使用5.6 完成 总结 前言 spingcloud微服务等每次部署到服务器上&#xff0c;都需要本地…