当前位置: 首页 > article >正文

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


http://www.kler.cn/a/388436.html

相关文章:

  • MySQL数据库:SQL语言入门 【下】(学习笔记)
  • ❤React-React 组件基础(类组件)
  • 94个属于一区且接受医工交叉领域投稿的期刊汇总|个人观点·24-11-13
  • react 中 FC 模块作用
  • Vue7种组件之间通信方式
  • RHCE web解析、dns配置、firewalld配置实验
  • Python pandas库:强大的数据处理工具
  • NoSQL大数据存储技术测试(2)NoSQL数据库的基本原理
  • DU模拟器(S5040A Open RAN Studio Player and Capture Appliance)
  • OSS和FastDFS的详细比较
  • 宝塔面板中使用Acme SSL.cn申请的免费HTTPS SSL证书安装步骤
  • 如何进行数据库连接池的参数优化?
  • 默认 iOS 设置使已锁定的 iPhone 容易受到攻击
  • 2024-11-01 - 统一身份认证 - OpenLdap - 中间件 - 流雨声
  • 【SAP FICO】财务三大报表_2-进阶(杜邦分析法、资产负债表-数据表结构、取数逻辑)
  • DOM事件监听 (鼠标事件,键盘事件,表单事件)
  • 【.Net Core/.Net8教程】巧用 C# 8.0 切片语法:高效处理数组和字符串
  • 【微服务】Docker 容器化
  • 两个matlab在线编译网站
  • golang常见面试题-基础篇
  • MATLAB课程:AI工具辅助编程——MATLAB+LLMs
  • 【基础解读】(PYG)Design of Graph Neural Networks——Heterogeneous Graph Learning
  • 存算分离与计算向数据移动:深度解析与Java实现
  • Linux【基础篇】T
  • k8s-service、endpoints、pod之间是怎么进行网络互通的
  • Vue 状态管理工具vuex