spring gateway 动态路由

news2024/11/14 14:22:51

##yml配置

spring:
  application:
    name: public-gateway
#  cloud:
#    gateway:
#      routes:
#        - id: mybatis-plus-test # 路由的唯一标识
#          uri: http://192.168.3.188:9898 # 目标服务的地址
#          predicates:
#            - Path=/test/** # 匹配以 /user/ 开头的请求路径
#          filters:
#            - AddRequestHeader=X-Request-Example, Example # 添加一个请求头
#            - AddRequestParameter=param1, value1 # 添加一个请求参数
server:
  port: 8180
logging:
  config: classpath:config/logback-spring.xml

##DynamicRoutesService动态路由

ApplicationEventPublisherAware得到publisher发布事件刷新路由缓存

ApplicationRunner设置路由

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class DynamicRoutesService implements ApplicationEventPublisherAware, ApplicationRunner {

    @Autowired
    private RouteLocator routeLocator;

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    private ApplicationEventPublisher publisher;

    private void loadDynamicRoutes() {
        routeDefinitionWriter.save(Mono.just(createRoute())).subscribe();
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        loadDynamicRoutes();
        publisher.publishEvent(new RefreshRoutesEvent(this));
    }

    public RouteDefinition createRoute() {
        PredicateDefinition predicateDefinition = new PredicateDefinition();
        List<PredicateDefinition> predicates = new ArrayList<>();
        predicates.add(predicateDefinition);
        Map<String, String> argsPredicate = new LinkedHashMap<>();
        
        argsPredicate.put("key0", "/test/**");
        predicateDefinition.setName("Path");
        predicateDefinition.setArgs(argsPredicate);

        FilterDefinition filterDefinition = new FilterDefinition();
        List<FilterDefinition> filters = new ArrayList<>();
        filters.add(filterDefinition);
        Map<String, String> argsFilter = new LinkedHashMap<>();
        
        argsFilter.put("name", "X-Request-Example");
        argsFilter.put("value", "Example");

        filterDefinition.setName("AddRequestHeader");
        filterDefinition.setArgs(argsFilter);

        RouteDefinition routeDefinition = new RouteDefinition();
        routeDefinition.setUri(URI.create("http://192.168.3.104:9898"));
        routeDefinition.setOrder(1);
        routeDefinition.setId("mybatis-plus-test");
        routeDefinition.setPredicates(predicates);
        routeDefinition.setFilters(filters);
        return routeDefinition;
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }

}

##publisher.publishEvent(new RefreshRoutesEvent(this));发布事件。调用CachingRouteLocator刷新缓存源码

private final Map<String, List> cache = new ConcurrentHashMap<>();

@Override
	public void onApplicationEvent(RefreshRoutesEvent event) {
		try {
			fetch().collect(Collectors.toList()).subscribe(list -> Flux.fromIterable(list)
					.materialize().collect(Collectors.toList()).subscribe(signals -> {
						applicationEventPublisher
								.publishEvent(new RefreshRoutesResultEvent(this));
						cache.put(CACHE_KEY, signals);
					}, throwable -> handleRefreshError(throwable)));
		}
		catch (Throwable e) {
			handleRefreshError(e);
		}
	}

##fetch方法

private Flux<Route> fetch() {
		return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);
	}

##fetch方法通过CompositeRouteLocator获取路由

@Override
	public Flux<Route> getRoutes() {
		return this.delegates.flatMapSequential(RouteLocator::getRoutes);
	}

##spring gateway 请求阶段查找路由

从CachingRouteLocator缓存中查找

##AsyncPredicate.DefaultAsyncPredicate.apply 判断路径是否匹配

 ##匹配方法

 

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

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

相关文章

论文1—《基于卷积神经网络的手术机器人控制系统设计》文献阅读分析报告

论文报告&#xff1a;基于卷积神经网络的手术机器人控制系统设计 摘要 本研究针对传统手术机器人控制系统精准度不足的问题&#xff0c;提出了一种基于卷积神经网络的手术机器人控制系统设计。研究设计了控制系统的总体结构&#xff0c;并选用PCI插槽上直接内插CAN适配卡作为上…

OpenHarmony-1.启动流程

OpenHarmony启动流程 1.kernel的启动 流程图如下所示&#xff1a;   OpenHarmony(简称OH)的标准系统的底层系统是linux&#xff0c;所以调用如下代码&#xff1a; linux-5.10/init/main.c: noinline void __ref rest_init(void) {struct task_struct *tsk;int pid;rcu_sch…

Python Plotly 库使用教程

Python Plotly 库使用教程 引言 数据可视化是数据分析中至关重要的一部分&#xff0c;它能够帮助我们更直观地理解数据、发现潜在的模式和趋势。Python 提供了多种数据可视化库&#xff0c;其中 Plotly 是一个功能强大且灵活的库&#xff0c;支持交互式图表的创建。与静态图表…

校园交友系统的设计与实现(开源版+三端交付+搭建+售后)

系统基础架构 采用UniApp进行开发&#xff0c;UniApp是一个使用Vue.js开发所有前端应用的框架&#xff0c;它支持编译为H5、小程序、App等多个平台。 使用PHP作为后端开发语言&#xff0c;PHP是一种广泛使用的开源脚本语言&#xff0c;尤其适用于Web开发&#xff0c;并可高效…

SQL 外连接

1 外连接 外连接是一种用于结合两个或多个表的方式&#xff0c;返回至少一个表中的所有记录。 左外连接 LEFT JOIN&#xff0c;左表为驱动表&#xff0c;右表为从表。返回驱动表的所有记录以及从表中的匹配记录。如果从表没有匹配&#xff0c;则结果中从表的部分为NULL。 右…

死磕grass平台

Grass平台:重塑互联网价值与AI数据采集的革新之路 引言&#xff1a;互联网资源的新范式 在当今数字时代,大多数互联网用户面临着一个共同但鲜少被关注的现象:我们付费购买的带宽资源往往没有被充分利用。想象一下,当你订购了100 Mbps的网络服务,在浏览新闻或查看邮件时,实际可…

Spring boot + Vue2小项目基本模板

Spring boot Vue2小项目基本模板 基本介绍基本环境安装项目搭建最终效果展示 基本介绍 项目来源哔哩哔哩的青戈&#xff0c;跟着学习搭建自己的简单vue小项目&#xff1b;看别人的项目总觉得看不懂&#xff0c;需要慢慢打磨 这里目前只简单的搭建了菜单导航和表格页面&#x…

大数据面试题--kafka夺命连环问(后10问)

目录 16、kafka是如何做到高效读写&#xff1f; 17、Kafka集群中数据的存储是按照什么方式存储的&#xff1f; 18、kafka中是如何快速定位到一个offset的。 19、简述kafka中的数据清理策略。 20、消费者组和分区数之间的关系是怎样的&#xff1f; 21、kafka如何知道哪个消…

用vscode编写verilog时,如何有信号定义提示、信号定义跳转(go to definition)、模块跳转这些功能

&#xff08;一&#xff09;安装插件SystemVerilog - Language Support 安装一个vscode插件即可&#xff0c;插件叫SystemVerilog - Language Support。虽然说另一个插件“Verilog-HDL/SystemVerilog/Bluespec SystemVerilog”也有信号提示及定义跳转功能&#xff0c;但它只能提…

万字长文解读深度学习——Transformer

&#x1f33a;历史文章列表&#x1f33a; 深度学习——优化算法、激活函数、归一化、正则化深度学习——权重初始化、评估指标、梯度消失和梯度爆炸深度学习——前向传播与反向传播、神经网络&#xff08;前馈神经网络与反馈神经网络&#xff09;、常见算法概要汇总万字长文解读…

Leecode热题100-35.搜索插入位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2示例 2: 输入:…

LabVIEW环境监测系统

随着环境问题的日益严重&#xff0c;环境参数的实时监测成为保障公共健康和生态平衡的重要手段。开发了一款基于LabVIEW开发的环境监测系统&#xff0c;能够对大气中的温度、湿度及二氧化硫浓度进行实时监测&#xff0c;并提供数据存储和超阈值报警功能。 系统组成 本系统由下…

7.4、实验四:RIPv2 认证和触发式更新

源文件 一、引言&#xff1a;为什么要认证和采用触发式更新&#xff1f; 1. RIP v2 认证 RIP&#xff08;Routing Information Protocol&#xff09;版本 2 添加了认证功能&#xff0c;以提高网络的安全性。认证的作用主要包括以下几点&#xff1a; 防止路由欺骗 RIP v1 是不…

人力资源招聘系统-提升招聘效率与质量的关键工具

在当今这个竞争激烈的商业环境中&#xff0c;企业要想在市场中立于不败之地&#xff0c;关键在于拥有高素质的人才队伍。然而&#xff0c;传统的招聘方式往往效率低下&#xff0c;难以精准匹配企业需求与人才特质&#xff0c;这无疑给企业的发展带来了不小的挑战。 随着科技的飞…

【Linux系统编程】第四十六弹---线程同步与生产消费模型深度解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、Linux线程同步 1.1、同步概念与竞态条件 1.2、条件变量 1.2.1、认识条件变量接口 1.2.2、举例子认识条件变量 1.2.3、…

UAV-VisLoc:中国11地大规模无人机视觉定位数据集

2024-05-16&#xff0c;由中科院、北京邮电大学和香港城市大学联合创建了UAV-VisLoc数据集&#xff0c;这个数据集通过收集中国11个不同地点的无人机图像和卫星地图&#xff0c;为无人机在失去全球导航卫星系统(GNSS)信号时提供精确的经纬度坐标定位&#xff0c;具有重要的实际…

el-table 行列文字悬浮超出屏幕宽度不换行的问题

修改前的效果 修改后的效果 ui框架 element-plus 在网上找了很多例子都没找到合适的 然后这个东西鼠标挪走就不显示 控制台也不好调试 看了一下El-table的源码 他这个悬浮文字用的el-prpper 包着的 所以直接改 .el-table .el-propper 设置为max-width:1000px 就可以了 吐槽一…

SystemVerilog学习笔记(十):进程/细粒度进程控制

进程 进程或线程是作为独立实体执行的任何代码片段。fork-join块创建并行运行的不同线程。在下面的图-1中&#xff0c;可以看到进程的类型和进程控制。 序号进程描述1.fork-join只有所有子线程执行完毕时&#xff0c;父线程才会执行。2.fork-join_any只有任何一个子线程执行完…

MySQL技巧之跨服务器数据查询:高级篇-先调用A数据库的MySql存储过程再复制到B数据库的表中

MySQL技巧之跨服务器数据查询&#xff1a;高级篇-先调用A数据库的MySql存储过程再复制到B数据库的表中 基础篇已经描述&#xff1a;借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的…

【数据结构】10.线索二叉树

一、线索二叉树的产生 采用先序、中序、后序三种方法遍历二叉树后都可以得到一个线性序列&#xff0c;序列上的每一个结点&#xff08;除了第一个和最后一个&#xff09;都有一个前驱和一个后继&#xff0c;但是&#xff0c;这个线性序列只是逻辑的概念&#xff0c;不是物理结…