热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringCloudGateway扩展动态路由

SpringCloudGateway扩展动态路由路由配置配置文件spring:application:name:sc-gwcloud:nacos:discovery:serv

Spring Cloud Gateway 扩展动态路由


路由配置


配置文件

spring:application:name: sc-gwcloud:nacos:discovery:server-addr: 127.0.0.1:8848config:server-addr: 127.0.0.1:8848file-extension: ymlshared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}gateway:discovery:locator:enabled: truelower-case-service-id: trueroutes: # Route Predicate Factories- id: nacos-getway-provider #自定义的路由ID,保持唯一uri: lb://nacos-provider #目标服务地址,以lib://开头(lb代表从注册中心获取服务)predicates: #路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。# - Path=/demo/service #路由规则,为每一个服务定义一个唯一的路由前缀,所有以路由前缀开头的请求都路由到对应的服务- Path=/service-02/** #Path Route Predicate Factoryfilters: # GatewayFilter Factories-路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器的作用域是特定的路由。- StripPrefix=1- id: nacos-getway-consumeruri: lb://nacos-comsumerpredicates:# - Path=/demo/serviceFeign- Path=/service-01/**filters:- StripPrefix=1- id: sc-authuri: lb://sc-authpredicates:- Path=/sc-auth/**filters:- StripPrefix=1

硬编码配置

@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {return builder.routes().route("nacos-getway-provider",r -> r.path("/service-02/**").filters(f -> f.stripPrefix(2)).uri("lb://nacos-provider")).build();
}

Spring Cloud Gateway 原生配置路由的方式有配置文件、硬编码。但是这两种方式存在明显的缺陷:修改路由之后必须重新启动服务路由才能生效,非常不灵活。

路由初始化过程



  1. 不管是哪种方式配置路由,每一条路由信息最终都被封装为 RouteDefination。

  2. RouteDefinationLocator 是路由信息的装载器它只有一个方法 getRouteDefinitions()。

  3. RouteDefinationLocator 有多个实现类分别对应不同的路由加载方式。



  • CachingRouteDefinitionLocator 是 RouteDefinationLocator 的一个包装类,它负责将读到的路由信息缓存到 Map。

  • CompositeRouteDefinitionLocator 是 RouteDefinationLocator 的一个包装类,它负责组合RouteDefinationLocator 的各个实现类。

  • PropertiesRouteDefinitionLocator 从配置文件中加载路由信息。

  • DiscoveryClientRouteDefinitionLocator 从注册中心加载路由信息。

  • RouteDefinitionRepository 从存储器中加载路由信息。这里的存储器包括内存、数据库



  1. RouteDefinitionRepository 有一个实现类 InMemoryRouteDefinitionRepository 。

    • InMemoryRouteDefinitionRepository 从内存中加载路由信息。

    • 没有 RouteDefinitionRepository 实例的情况下默认加载 InMemoryRouteDefinitionRepository 。

    • 通过实现 RouteDefinitionRepository 来实现动态路由。



  2. 路由加载

    • PropertiesRouteDefinitionLocator --> CompositeRouteDefinitionLocator

    • RouteDefinitionRepository --> CompositeRouteDefinitionLocator

    • DiscoveryClientRouteDefinitionLocator

    • CompositeRouteDefinitionLocator




扩展思路



  • 通过实现 RouteDefinitionRepository 接口扩展 Spring Cloud Gateway 支持从 Redis 中读取路由信息。



  • 加入二级缓存(Map)。在实现 RouteDefinitionRepository 接口的getRouteDefinations() 方法时首先从二级缓存中读取路由信息,二级缓存为空时从 Redis 中 读取路由信息,再将路由信息写入到二级缓存中。



  • 在在实现 RouteDefinitionRepository 接口的 save() / delete() 方法时通过 Redis 的发布订阅功能清空二级缓存



  • 服务启动时通过监听WebServerIntialedEvent事件进行路由初始化。初始化过程中将 Mysql 中存储的路由信息读取出来存储到 Redis 中。



  • 路由修改时首先更新 Redis ,再将路由信息持久化到 Mysql 中。通过发布 RefreshRoutesEvent 事件通过 Spring Cloud Gateway 更新路由。通过 Redis 的发布订阅功能清空二级缓存。持久化失败时回滚路由,通过发布事件重新进行路由初始化操作。




具体实现



  1. 前端页面。

  2. Controller 提供路由查询、更新接口。

  3. Service 提供路由查询、更新具体实现。

  4. 通过继承 RouteDefination 类支持序列化。创建 RouteDefinationVo 类封装数据库中存储的路由信息。

  5. 实现 RouteDefinationsRepository 接口重写 save() / delete() / getDefinations() 方法。

  6. 通过继承 ApplicationEvent 实现一个 DynamicRouteInitEvent 事件类 ,通过@EventListener 注解监听 WebServerIntialedEvent 、DynamicRouteInitEvent 事件对路由进行初始化。

  7. 创建 Redis 监听器,监听 topic 在Redis缓存更新时向指定的 topic 发布消息清空二级缓存或者重新初始化路由。

  8. 扩展 Redis 支持存储 Hash 形式的 value。


推荐阅读
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • Centos7搭建ELK(Elasticsearch、Logstash、Kibana)教程及注意事项
    本文介绍了在Centos7上搭建ELK(Elasticsearch、Logstash、Kibana)的详细步骤,包括下载安装包、安装Elasticsearch、创建用户、修改配置文件等。同时提供了使用华为镜像站下载安装包的方法,并强调了保证版本一致的重要性。 ... [详细]
  • 本文介绍了网页播放视频的三种实现方式,分别是使用html5的video标签、使用flash来播放以及使用object标签。其中,推荐使用html5的video标签来简单播放视频,但有些老的浏览器不支持html5。另外,还可以使用flash来播放视频,需要使用object标签。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Ubuntu 9.04中安装谷歌Chromium浏览器及使用体验[图文]
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
author-avatar
5257wals_220
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有