1、实现动态路由的关键是RouteDefinitionRepository接口,该接口存在一个默认实现(InMemoryRouteDefinitionRepository)

通过名字我们应该也知道该实现是将配置文件中配置的信息加载到内存中。因此无法实现动态路由。

2、如果想实现动态路由,我们可以参考默认实现,自己编写一个实现,代码如下:

import static java.util.Collections.synchronizedMap;

@Component
public class UnifiedRouteRepositoryImpl implements RouteDefinitionRepository { public final Map<String, RouteDefinition> routes =
synchronizedMap(new LinkedHashMap<>()); @Override
public Flux<RouteDefinition> getRouteDefinitions() {
return Flux.fromIterable(routes.values());
} @Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return route.flatMap( r -> {
routes.put(r.getId(), r);
return Mono.empty();
});
} @Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id -> {
if (routes.containsKey(id)) {
routes.remove(id);
return Mono.empty();
}
return Mono.defer(() -> Mono.error(new NotFoundException("RouteDefinition not found: "+routeId)));
});
} }

 3、虽然我们模仿默认实现,实现了自己的路由处理,但是我们还存在几个问题,就是如何将数据库中的数据加载到Map<String, RouteDefinition> routes =synchronizedMap(new LinkedHashMap<>());

还有就是当数据库数据变化时,如何刷新routes?

CommandLineRunner 作用当项目启动以后调用该类中的run(String... args)方法
ApplicationEventPublisherAware 可以理解为观察者模式,当存在数据变化时,就刷新缓存中的路由
@Slf4j
@Component
public class GatewayServiceHandler implements ApplicationEventPublisherAware, CommandLineRunner {

@Autowired
@Qualifier(value = "unifiedRouteRepositoryImpl")
private RouteDefinitionWriter routeDefinitionWriter;

  //该类需要你自己编写(将数据库中的动态路由加载到内存中)
@Autowired
private RouteRepository routeRepository; private ApplicationEventPublisher publisher; @Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
} @Override
public void run(String... args){
this.loadRouteConfig();
} public void loadRouteConfig() {
List<Map<String, Object>> lists = routeRepository.getListAll();
lists.forEach(r ->{
RouteDefinition route = new RouteDefinition();
PredicateDefinition predicate = new PredicateDefinition();
Map<String, String> predicateParams = new HashMap<>(2);
FilterDefinition filter = new FilterDefinition();
Map<String, String> filterParams = new HashMap<>(2);
//设置Id
route.setId((String)r.get("routeId"));
try {
route.setUri(new URI((String)r.get("uri")));
} catch (URISyntaxException e) {
e.printStackTrace();
}
predicate.setName((String)r.get("predicateName"));
predicateParams.put("pattern",(String)r.get("predicateArgs"));
predicate.setArgs(predicateParams);
if(!StringUtils.isBlank(predicate.getName())){
route.setPredicates(Arrays.asList(predicate));
} filter.setName((String)r.get("filterName"));
filterParams.put("_genkey_0",(String)r.get("filterArgs"));
filter.setArgs(filterParams);
if(!StringUtils.isBlank(filter.getName())){
route.setFilters(Arrays.asList(filter));
}
routeDefinitionWriter.save(Mono.just(route)).subscribe();
});
this.publisher.publishEvent(new RefreshRoutesEvent(this)); } public void deleteRoute(String routeId){
routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
}

  

Spring Cloud Gateway之动态路由(数据库版)的更多相关文章

  1. Spring Cloud Gateway的动态路由怎样做?集成Nacos实现很简单

    一.说明 网关的核心概念就是路由配置和路由规则,而作为所有请求流量的入口,在实际生产环境中为了保证高可靠和高可用,是尽量要避免重启的,所以实现动态路由是非常有必要的:本文主要介绍 Spring Clo ...

  2. Spring cloud gateway 如何在路由时进行负载均衡

    本文为博主原创,转载请注明出处: 1.spring cloud gateway 配置路由 在网关模块的配置文件中配置路由: spring: cloud: gateway: routes: - id: ...

  3. Spring Cloud Zuul的动态路由怎样做?集成Nacos实现很简单

    一.说明 网关的核心概念就是路由配置和路由规则,而作为所有请求流量的入口,在实际生产环境中为了保证高可靠和高可用,是尽量要避免重启的,所以实现动态路由是非常有必要的:本文主要介绍实现的思路,并且以Na ...

  4. spring cloud学习(四) 动态路由

    Zuul的主要功能是路由和过滤器.路由功能是微服务的一部分,zuul实现了负载均衡. 1.1 新建模块zuul pom.xml <?xml version="1.0" enc ...

  5. Spring Cloud Zuul实现动态路由

    1.添加依赖 2.启动类上添加注解 3.配置文件 zuul.ignored-services配置需要忽略的服务,多个用逗号分隔 注释zuul.ignored-services 前: 注释zuul.ig ...

  6. Spring Cloud Alibaba | Nacos动态网关路由

    Spring Cloud Alibaba | Gateway基于Nacos动态网关路由 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud ...

  7. Spring Cloud Alibaba学习笔记(16) - Spring Cloud Gateway 内置的路由谓词工厂

    Spring Cloud Gateway路由配置的两种形式 Spring Cloud Gateway的路由配置有两种形式,分别是路由到指定的URL以及路由到指定的微服务,在上文博客的示例中我们就已经使 ...

  8. 使用Spring Cloud Gateway保护反应式微服务(一)

    反应式编程是使你的应用程序更高效的一种越来越流行的方式.响应式应用程序异步调用响应,而不是调用资源并等待响应.这使他们可以释放处理能力,仅在必要时执行处理,并且比其他系统更有效地扩展. Java生态系 ...

  9. Spring Cloud gateway 网关四 动态路由

    微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...

随机推荐

  1. 攻防世界 reverse BABYRE

    BABYRE   XCTF 4th-WHCTF-2017 int __cdecl main(int argc, const char **argv, const char **envp) { char ...

  2. 使用 Github Actions artifact 在 workflow job 之间共享数据

    (AgileConfig)[https://github.com/kklldog/AgileConfig] 在使用 react 编写UI后,变成了一个彻彻底底的前后端分离的项目,上一次解决了把reac ...

  3. 极简实用的Asp.NetCore模块化框架决定免费开源了

    背景 在开发这个框架之前,前前后后看过好几款模块化的框架,最后在一段时间内对ABP VNext痛下狠心,研究一段时间后,不得不说 ABP VNext的代码层面很规范,也都是一些最佳实践,开发出一个模块 ...

  4. 问题笔记 - element表格 操作状态值

    1.必须从传到表里的数据源中取值(scope.row.star)

  5. GO-02-helloworld

    package main /** package main表示一个可独立执行的程序,每个Go应用程序都需要包含一个名为main的包, 并且该包包含一个叫main()的函数(该函数是Go可执行程序的执行 ...

  6. 算法图解...pdf

    电子书资源:算法图解 书籍简介   本书示例丰富,图文并茂,以让人容易理解的方式阐释了算法,旨在帮助程序员在日常项目中更好地发挥算法的能量.书中的前三章将帮助你打下基础,带你学习二分查找.大O表示法. ...

  7. UT之最后一测

    经过前面几次文章的分享的UT的相关知识,今天接着分享UT相关最后一测文章,希望对大家在UT的学习中有一点点的帮助. Spring集成测试 有时候我们需要在跑起来的Spring环境中验证,Spring ...

  8. JPA之排序条件查询

    List<Monitoring> monitoringList = repository.findAll((root, query, cb) -> { List<Predica ...

  9. 1049 Counting Ones

    The task is simple: given any positive integer N, you are supposed to count the total number of 1's ...

  10. 数据分析处理之PCA OLSR PCR PLSR(NIPALS)及其Matlab代码实现

    传统的OLS(普通最小二乘)方法无法解决样本数据的共线性(multicollinearity)问题,如果你的数据样本中每个特征变量具有共线性,那么使用基于PCA的PCR和PLSR方法对数据样本进行回归 ...