spring gateway 动态路由

##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;
    }

}

##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);
	}

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

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

相关文章

ssm079基于SSM框架云趣科技客户管理系统+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;客户管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本客户管理系统就是在这…

C语言 | Leetcode C语言题解之第556题下一个更大元素III

题目&#xff1a; 题解&#xff1a; int nextGreaterElement(int n){int x n, cnt 1;for (; x > 10 && x / 10 % 10 > x % 10; x / 10) {cnt;}x / 10;if (x 0) {return -1;}int targetDigit x % 10;int x2 n, cnt2 0;for (; x2 % 10 < targetDigit; x2…

华为大变革?仓颉编程语言会代替ArkTS吗?

在华为鸿蒙生态系统中&#xff0c;编程语言的选择一直是开发者关注的焦点。近期&#xff0c;华为推出了自研的通用编程语言——仓颉编程语言&#xff0c;这引发了关于仓颉是否会取代ArkTS的讨论。本文将从多个角度分析这两种语言的特点、应用场景及未来趋势&#xff0c;探讨仓颉…

Linux:基本开发工具

一&#xff1a;编辑器vim 1.1vim的基本概念 vim其实有多重模式&#xff0c;这里我们主要了解vim的三种模式&#xff0c;分别是命令模式&#xff08;command mode&#xff09;,插入模式(Insert mode)和底行模式(lst line mode) 正常/普通/命令模式(Normal mode) …

第14张 GROUP BY 分组

一、分组功能介绍 使用group by关键字通过某个字段进行分组&#xff0c;对分完组的数据分别 “SELECT 聚合函数”查询结果。 1.1 语法 SELECT column, group_function(column) FROM table [WHERE condition] [GROUP BY group_by_expression] [ORDER BY column]; 明确&#…

TVM计算图分割--BYOC框架

文章目录 BYOC架构算子标注单算子标注复合算子标注Cost-based PartitionCodegenCodegen for C代码生成流程概览代码生成工程实现实现CodegenC实现CSourceCodegenCodegen for JSON实现JsonCodegenRuntimeJSONRuntime参考随着后端设备数量激增,为达到较高的效果在这些设备上,对…

计算机毕业设计Python+卷积神经网络股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

qt QShortcut详解

1、概述 QShortcut是Qt框架中的一个类&#xff0c;它提供了一种创建键盘快捷键的方式。通过QShortcut&#xff0c;开发者可以将特定的键盘组合&#xff08;如CtrlC、AltF4等&#xff09;与应用程序中的动作&#xff08;如复制、关闭窗口等&#xff09;关联起来。当用户在应用程…

C++OJ_二叉树的层序遍历

✨✨ 欢迎大家来到小伞的大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C_OJ 小伞的主页&#xff1a;xiaosan_blog 二叉树的层序遍历 102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff0…

The Rank-then-Encipher Approach

原始观点 Format-Preserving Encryption 4 The Rank-then-Encipher Approach 引用1 Hybrid diffusion-based visual image encryption for secure cloud storage 2.2 Sum-preserving encryption Bellare introduced the concept of format-preserving encryption (FPE)…

DolphinDB 与南方科技大学联合授课啦!

11月1日&#xff0c;南方科技大学商学院和 DolphinDB 联合举办了高校课程讲座。讲座由南方科技大学商学院高级研究学者冯鹏举主持&#xff0c;DolphinDB 创始人兼 CEO 周小华博士、某百亿私募数据平台架构师潜蛟老师进行精彩演讲。 Part 1 : 大数据时代下数据库架构革新与生态…

IDM扩展添加到Edge浏览器

IDM扩展添加到Edge浏览器 一般情况下&#xff0c;当安装IDM软件后&#xff0c;该软件将会自动将IDM Integration Module浏览器扩展安装到Edge浏览器上&#xff0c;但在某些情况下&#xff0c;需要我们手动安装&#xff0c;以下为手动安装步骤 手动安装IDM扩展到Edge浏览器 打…

403 Request Entity Too Lager(请求体太大啦)

昨天收到 QA 的生产报障&#xff0c;说是测试环境的附件上传功能报了 403 的错误&#xff0c;错误信息&#xff1a;403 Request Entity Too Lager。我尝试复现问题&#xff0c;发现传个几兆的文件都费劲啊&#xff0c;一传一个失败。不用说&#xff0c;项目用到 ng 代理&#x…

HARCT 2025 新增分论坛2:机器人系统智能控制

会议名称&#xff1a;机电液一体化与先进机器人控制技术国际会议 会议简称&#xff1a;HARCT 2025 大会时间&#xff1a;2025年1月3日-6日 大会地点&#xff1a;中国桂林 主办单位&#xff1a;桂林航天工业学院、广西大学、桂林电子科技大学、桂林理工大学 协办单位&#…

网络世界中的侦察兵----ICMP

前言 学习了IP协议后&#xff0c;都知道IP协议本身是不提供可靠性保障的&#xff0c;那么数据包在这么复杂的互联网环境中传输&#xff0c;总会遇到问题&#xff0c;如果遇到问题后&#xff0c;被丢弃、无回应&#xff0c;可能作为工程师的我们来说都不知道发生了什么事&#…

从0开始学习机器学习--Day21--算法的评估标准

准确率和召回率(precision and recall) 在上一章我们提到了在每次运行算法时通过返回一个实数值来判断算法的好坏&#xff0c;但是我们该如何构建这个实数的计算公式呢&#xff0c;毕竟这关乎于我们对算法的判断&#xff0c;不能过于夸大或贬低。有一个典型的会被影响的很大例…

集群架构中Lua脚本的限制以及出现的报错

&#x1f680; 博主介绍&#xff1a;大家好&#xff0c;我是无休居士&#xff01;一枚任职于一线Top3互联网大厂的Java开发工程师&#xff01; &#x1f680; &#x1f31f; 在这里&#xff0c;你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人&#xff0c;我不仅热衷…

快速傅里叶变换(FFT)基础(附python实现)

对于非专业人士&#xff0c;傅里叶变换一直是一个神秘的武器&#xff0c;它可以分析出不同频域的信息&#xff0c;从时域转换到频域&#xff0c;揭示了信号的频率成分&#xff0c;对于数字信号处理&#xff08;DSP&#xff09;、图像、语音等数据来说&#xff0c;傅里叶变换是最…

python数据结构操作与可视化的应用

Python具有丰富的数据结构操作和可视化库&#xff0c;可以进行各种数据结构的创建、编辑和分析&#xff0c;并将结果可视化。以下是几个常见的Python数据结构操作和可视化的应用示例&#xff1a; 1. 列表&#xff08;List&#xff09;操作和可视化&#xff1a; - 创建列表&a…

DataFrame

目录 一、创建DataFrame二、Sql语法三、DSL语法四、RDD与DataFrame互相转换 一、创建DataFrame 在SparkSql中SparkSession是创建DataFrame和执行Sql的入口&#xff0c;创建DataFrame有三种方式&#xff1a; 通过Spark的数据源进行创建 从一个存在的RDD进行转换 从Hive Tabl…