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. (二)SpringBoot启动过程的分析-环境信息准备

    -- 以下内容均基于2.1.8.RELEASE版本 由上一篇SpringBoot基本启动过程的分析可以发现在run方法内部启动SpringBoot应用时采用多个步骤来实现,本文记录启动的第二个环节:环 ...

  2. C#异步编程由浅入深(一)

    一.什么算异步?   广义来讲,两个工作流能同时进行就算异步,例如,CPU与外设之间的工作流就是异步的.在面向服务的系统中,各个子系统之间通信一般都是异步的,例如,订单系统与支付系统之间的通信是异步的 ...

  3. java例题_23 递归求年龄

    1 /*23 [程序 23 求岁数] 2 题目:有 5 个人坐在一起,问第五个人多少岁,他说比第 4 个人大 2 岁.问第 4 个人岁数,他说比第 3 个 3 人大 2 岁.问第三个人,又说比第 2 ...

  4. SqlServer触发器的创建与使用

    前言 上期我们介绍了SqlServer的视图和存储过程创建与使用,这期我们介绍一下触发器. 有需要回顾的可以电梯直达看一下: SqlServer视图的创建与使用 SqlServer存储过程的创建与使用 ...

  5. 20182217刘洪宇EXP3_免杀原理

    免杀 一般是对恶意软件做处理,让它不被杀毒软件所检测.也是渗透测试中需要使用到的技术. 要做好免杀,就时清楚杀毒软件(恶意软件检测工具)是如何工作的.AV(Anti-virus)是很大一个产业.其中主 ...

  6. 为什么数据库字段要使用NOT NULL?

    最近刚入职新公司,发现数据库设计有点小问题,数据库字段很多没有NOT NULL,对于强迫症晚期患者来说,简直难以忍受,因此有了这篇文章. 基于目前大部分的开发现状来说,我们都会把字段全部设置成NOT ...

  7. Apache Hudi:CDC的黄金搭档

    1. 介绍 Apache Hudi是一个开源的数据湖框架,旨在简化增量数据处理和数据管道开发.借助Hudi可以在Amazon S3.Aliyun OSS数据湖中进行记录级别管理插入/更新/删除.AWS ...

  8. [hash]集合

    集合 题目描述 给定两个集合A.B,集合内的任一元素x满足1 ≤ x ≤ 109,并且每个集合的元素个数不大于105.我们希望求出A.B之间的关系. 任 务 :给定两个集合的描述,判断它们满足下列关系 ...

  9. 基于vite2的react脚手架

    vite-react-boilerplate 开发编译 yarn start 启动开发 yarn build 启动编译 代码质量和风格 husky/lint-staged/eslint/prettie ...

  10. Java后端进阶-网络编程(Netty零拷贝机制)

    package com.study.hc.net.netty.demo; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled ...