• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

SpringCloud Gateway 利用 Mysql 实现动态路由的方法

java 搞代码 4年前 (2022-01-05) 38次浏览 已收录 0个评论
文章目录[隐藏]

这篇文章主要介绍了SpringCloud Gateway 利用 Mysql 实现动态路由的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

需求描述

标准网关动态路由功能是重要的一环,将路由、断言以及过滤器信息,持久化到 Mysql 中,通过配置后台页面实现路由、断言、以及过滤器等配置的增删改查。

Spring Cloud Gateway 路由及黑白名单实现背景 Spring Cloud 路由API

Spring Cloud Gateway 通过定义 RouteDefinitionRepository 来实现动态路由.

 //保存路由缓存 public interface RouteDefinitionWriter { Mono save(Mono route); Mono delete(Mono routeId); }
 //获取路由缓存 public interface RouteDefinitionLocator { Flux getRouteDefinitions(); }

Spring Cloud 配置文件路由加载方式

 public class PropertiesRouteDefinitionLocator implements RouteDefinitionLocator { private final GatewayProperties properties; public PropertiesRouteDefinitionLocator(GatewayProperties properties) { this.properties = properties; } @Override public Flux getRouteDefinitions() { return Flux.fromIterable(this.properties.getRoutes()); } }

Spring Cloud 黑白名 FilterFactory

利用 Spring Cloud Gateway 声明的一个工厂接口 GatewayFilterFactory, 定义 黑白名单过滤器

BlacklistGatewayFilterFactory 类图

WhitelistGatewayFilterFactory 类图

动态路由设计 Spring Cloud Gateway 路由实体类

Spring Cloud Gateway 通过定义 RouteDefinition 类装载路由信息。

 package org.springframework.cloud.gateway.route; public class RouteDefinition { //路由 ID @NotEmpty private String id = UUID.randomUUID().toString(); //断言数组 @NotEmpty @Valid private List predicates = new ArrayList(); //过滤器数组 @Valid private List filters = new ArrayList(); // 路由地址 @NotNull private URI uri; // 路由顺序 private int order = 0; }

数据库设计

路由表

 drop table if exists gateway_route_t; create table if not exists gateway_route_t ( ID     int auto_increment primary key, ROUTE_ID  varchar(255) not null comment '路由ID', ROUTE_ORDER int default 0 null comment '路由顺序', URI     varchar(255) not null comment '路由路径', VALID    int default 1 not null comment '是否有效:0-无效,1-有效', CREATE_USER varchar(200) null comment '创建人', CREATE_TIME datetime   null comment '创建时间', UPDATE_USER varchar(200) null comment '修改人', UPDATE_TIME datetime   null comment '修改时间', constraint idx_ROUTE_ID_index unique (ROUTE_ID) ) comment '网关路由信息表' charset = utf8;

路由参数表

 drop table if exists gateway_route_param_t; create table if not exists gateway_route_param_t ( ID     int auto_increment primary key, ROUTE_ID  varchar(255) not null comment '路由ID', PARAM_NAME varchar(255) not null comment '参数name', PARAM_KEY  varchar(255) not null comment '参数 key', PARAM_VALUE varchar(255) not null comment '参数 value', TYPE    int    <i style="color:transparent">来源gaodai$ma#com搞$$代**码)网</i>  not null comment '参数类型,1为 predicate,2为过 filter', VALID    int default 1 not null comment '是否有效:0-无效,1-有效', CREATE_USER varchar(200) null comment '创建人', CREATE_TIME datetime   null comment '创建时间', UPDATE_USER varchar(200) null comment '修改人', UPDATE_TIME datetime   null comment '修改时间' ) comment '网关路由参数表' charset = utf8; create index idx_route_id on gateway_route_param_t (ROUTE_ID);

接口设计 接口定义

路由表配置接口

封装 gateway_route_t dao 层接口.

 /** *  路由表接口 * * @author 20024322 * @date 2020/12/24 13:20 */ public interface IRouteConfigService extends IService

路由参数表配置接口

封装 gateway_route_param_t dao 层接口.

 /** *  路由参数表接口 * * @author 20024322 * @date 2020/12/24 13:20 */ public interface IRouteParamConfigService extends IService

数据库路由服务接口

封装 路由表配置服务接口以及路由参数表配置接口, 对外层提供对数据库路由信息的操作.

 /** *  数据库路由服务 * * @author 20024322 * @date 2020/12/24 13:20 */ public interface IRoutePropertiesService

网关路由缓存接口

封装 RouteDefinitionRepository 接口,对外提供对网关路由缓存的刷新.

 /** *  网关缓存路由服务 * * @author 20024322 * @date 2020/12/24 13:20 */ public interface IGatewayRouteService extends ApplicationEventPublisherAware

路由事件监听接口

配置需要监听路由变化的 service 实现

 /** *  路由事件监听接口 * * @author 20024322 * @date 2020/12/24 13:20 */ public interface RouteEventListener extends ApplicationListener

数据库黑白名单配置接口

 /** *  API Filter 接口定义 * * @author 20024322 * @date 2020/12/24 13:20 */ public interface IApiFilterService

网关白名单缓存接口

提供指定路由 API 白名单check 监听路由事件

 /** *  API 白名单缓存接口 * * @author 20024322 * @date 2020/12/24 13:20 */ public interface IApiCacheService extends RouteEventListener

路由参数执行校验接口

封装 提供路由参数的校验的接口.

 /** *  路由参数校验 * * @author 20024322 * @date 2020/12/24 13:20 */ public interface IRouteValidateExecutorService

接口类图 路由及黑白名单类图

断言及过滤器封装类图

集群缓存刷新事件处理策略类图

路由初始化设计 重载 PropertiesRouteDefinitionLocator

 /** *  重写 PropertiesRouteDefinitionLocator bean * 将配置文件中的路由信息通过 MysqlRouteConfig 载入。 * * @author 20024322 * @date 2020/12/24 13:20 */ @Configuration @AutoConfigureBefore({MysqlRouteConfig.class}) public class PropertiesRouteConfig { @Bean public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator( GatewayProperties properties) { return new PropertiesRouteDefinitionLocator(new GatewayProperties()); } }

定义 initMysqlRouteDefinition Bean 加载数据库及配置文件的路由配置

 /** *  从Mysql中初始化路由信息 * 覆盖配置文件中的路由信息 * * @author 20024322 * @date 2020/12/24 13:20 */ @Configuration public class MysqlRouteConfig { private final IRoutePropertiesService routePropertiesService; private final IGatewayRouteService gatewayRouteService; public MysqlRouteConfig(IRoutePropertiesService routePropertiesService, IGatewayRouteService gatewayRouteService) { this.routePropertiesService = routePropertiesService; this.gatewayRouteService = gatewayRouteService; } /** * 初始化 gatewayProperties 中的 route * * @param gatewayProperties * @return */ @Bean public List initMysqlRouteDefinition(GatewayProperties gatewayProperties) { List gatewayPropertiesRoutes = gatewayProperties.getRoutes(); //初始化数据库路由信息 List routeDefinitionList = routePropertiesService.getRouteDefinitionList(); if (CollectionUtils.isEmpty(gatewayProperties.getRoutes()) && CollectionUtils.isEmpty(routeDefinitionList)) { throw new BizBaseException(HprmcExceptionCode.ROUTE_NOT_FOUND); } Set routeIds = routeDefinitionList.stream() .map(RouteDefinition::getId).collect(Collectors.toSet()); if (gatewayPropertiesRoutes.stream().anyMatch(r -> routeIds.contains(r.getId()))) { throw new BizBaseException(HprmcExceptionCode.ROUTE_INIT_CONFLICT); } //将配置文件中的路由信息添加到 InMemoryRouteDefinitionRepository 成员变量中 if (!CollectionUtils.isEmpty(gatewayPropertiesRoutes)) { gatewayPropertiesRoutes.forEach(gatewayRouteService::addInMemoryRouteRefresh); } //写到 InMemoryRouteDefinitionRepository 成员初始化缓存 if (!CollectionUtils.isEmpty(routeDefinitionList)) { routeDefinitionList.forEach(gatewayRouteService::addInMemoryRouteRefresh); } return routeDefinitionList; } }

到此这篇关于SpringCloud Gateway 利用 Mysql 实现动态路由的方法的文章就介绍到这了,更多相关SpringCloud Gateway 实现动态路由内容请搜索gaodaima搞代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持gaodaima搞代码网

以上就是SpringCloud Gateway 利用 Mysql 实现动态路由的方法的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:SpringCloud Gateway 利用 Mysql 实现动态路由的方法

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址