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. python之极简ATM系统示例

    """用户可登陆系统输错三次锁定账号用户可以创建新的用户名密码新用户初始账户设为0新用户可直接登陆系统用户登陆成功后可以选择业务类型用户数据可以根据业务修改输入Q随时退出 ...

  2. 「HTML+CSS」--自定义按钮样式【003】

    前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...

  3. 服务器安装部署-01-MySQL

    1 MySQL 1.1 安装 在root用户权限下 # 创建mysql用户和用户组,同时禁止登陆 shell> groupadd mysql shell> useradd -r -g my ...

  4. 配置redis 4.0.11 集群

    配置redis 4.0.11 集群 准备redis 软件和redis配置文件 启动Redis服务 /data/soft/redis/src/redis-check-aof --fix /log/red ...

  5. 显示目录下的内容--ls

    ls               显示当前目录下的所有文件或者文件夹,但不包括 . 和 .. ls -a                  显示当前目录下的所有文件或者文件夹 ls -l        ...

  6. 生产中常用的获取IP地址方法的总结

    从ifconfig命令的结果中筛选出除了lo网卡之外的所有IPv4地址 centos7 (1)ifconfig | awk '/inet / && !($2 ~ /^127/){pri ...

  7. [深搜]C. 【例题3】虫食算

    C . [ 例 题 3 ] 虫 食 算 题目解析 正解 : Dfs + 剪枝 依题意,把样例以加法的形式展现出来. 根据加法的性质,可以得出有两种情况:有进位和没有进位的. 而从百位到最高位的结果,又 ...

  8. 201871010130-周学铭 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 18卓越班 这个作业要求链接 实验三结对编程要求 我的课程学习目标 体验软件项目开发中的两人合作,练习结对编程(Pair programming).掌握Github协作开 ...

  9. Web协议详解与抓包实战,高效解决网络难题

    无论你是前后端工程师,还是运维测试,如果想面试更高的职位,或者要站在更高的角度去理解技术业务架构,并能在问题出现时快速.高效地解决问题,Web 协议一定是你绕不过去的一道坎. 旨在帮助你对各种常用 W ...

  10. C#与Python交互方式

    前言: 在平时工作中,需求有多种实现方式:根据不同的需求可以采用不同的编程语言来实现.发挥各种语言的强项 如:Python的强项是:数据分析.人工智能等 .NET 开发桌面程序界面比Python更简单 ...