热门标签 | 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。


推荐阅读
  • 本文详细介绍了如何使用C#实现不同类型的系统服务账户(如Windows服务、计划任务和IIS应用池)的密码重置方法。 ... [详细]
  • Hibernate全自动全映射ORM框架,旨在消除sql,是一个持久层的ORM框架1)、基础概念DAO(DataAccessorOb ... [详细]
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
  • 本文介绍了Tomcat的基本操作,包括启动、关闭及首次访问的方法,并详细讲解了如何在IDEA中创建Web项目,配置Servlet及其映射,以及如何将项目部署到Tomcat。 ... [详细]
  • 本文详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现分页功能。包括分页的基本概念、数据准备、前端分页栏的设计与实现、后端分页逻辑的编写以及最终的测试步骤。 ... [详细]
  • 解决Win10 1709版本文件共享安全警告问题
    每当Windows 10发布新版本时,由于兼容性问题往往会出现各种故障。近期,一些用户在升级至1709版本后遇到了无法访问共享文件夹的问题,系统提示‘文件共享不安全,无法连接’。本文将提供多种解决方案,帮助您轻松解决这一难题。 ... [详细]
  • MITM(中间人攻击)原理及防范初探(二)
    上一篇文章MITM(中间人攻击)原理及防范初探(一)给大家介绍了利用ettercap进行arp欺骗及劫持明文口令,后来我发现好友rootoorotor的文章介绍比我写的更透彻,所以基础利用大家可以参看 ... [详细]
  • Fiddler 安装与配置指南
    本文详细介绍了Fiddler的安装步骤及配置方法,旨在帮助用户顺利抓取用户Token。文章还涵盖了一些常见问题的解决方案,以确保安装过程顺利。 ... [详细]
  • 为何Compose与Swarm之后仍有Kubernetes的诞生?
    探讨在已有Compose和Swarm的情况下,Kubernetes是如何以其独特的设计理念和技术优势脱颖而出,成为容器编排领域的领航者。 ... [详细]
  • 本文详细介绍了如何在Mac操作系统中为IntelliJ IDEA配置更高的内存限制,以提高开发效率和性能。 ... [详细]
  • 在尝试加载支持推送通知的iOS应用程序的Ad Hoc构建时,遇到了‘no valid aps-environment entitlement found for application’的错误提示。本文将探讨此错误的原因及多种可能的解决方案。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 从理想主义者的内心深处萌发的技术信仰,推动了云原生技术在全球范围内的快速发展。本文将带你深入了解阿里巴巴在开源领域的贡献与成就。 ... [详细]
  • linux网络子系统分析(二)—— 协议栈分层框架的建立
    目录一、综述二、INET的初始化2.1INET接口注册2.2抽象实体的建立2.3代码细节分析2.3.1socket参数三、其他协议3.1PF_PACKET3.2P ... [详细]
  • 深入理解Java SE 8新特性:Lambda表达式与函数式编程
    本文作为‘Java SE 8新特性概览’系列的一部分,将详细探讨Lambda表达式。通过多种示例,我们将展示Lambda表达式的不同应用场景,并解释编译器如何处理这些表达式。 ... [详细]
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社区 版权所有