gataway动态路基于数据库读取路由信息进行路由网关拦截等功能
1:需要使用注册中心 nacos eureka 等都可以
2:需要重写gateway的方法

package com.lary.gatewaydemo.ceshi.service;import com.alibaba.fastjson.JSON;
import com.lary.gatewaydemo.ceshi.entity.GatewayRoute;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;import javax.annotation.Resource;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import static com.lary.gatewaydemo.ceshi.service.RedisRouteDefinitionRepository.GATEWAY_ROUTES;/*** @program: gateway* @description: sss* @author: lary* @create: 2021-08-05 15:28*/
@Slf4j
@Service
public class GatewayServiceHandler implements ApplicationEventPublisherAware, CommandLineRunner {@Autowiredprivate RedisRouteDefinitionRepository routeDefinitionWriter;private ApplicationEventPublisher publisher;@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.publisher = applicationEventPublisher;}@Autowiredprivate RedisTemplate redisTemplate;@Resourceprivate GatewayRouteService gatewayRouteService;@Overridepublic void run(String... args){this.loadRouteConfig();}public String loadRouteConfig() {log.info("====开始加载=====网关配置信息=========");//删除redis里面的路由配置信息redisTemplate.delete(GATEWAY_ROUTES);//从数据库拿到基本路由配置List<GatewayRoute> gatewayRouteList = gatewayRouteService.gatewayRoutes();gatewayRouteList.forEach(gatewayRoute -> {RouteDefinition definition=handleData(gatewayRoute);routeDefinitionWriter.save(Mono.just(definition)).subscribe();});this.publisher.publishEvent(new RefreshRoutesEvent(this));log.info("=======网关配置信息===加载完成======");return "success";}public void saveRoute(GatewayRoute gatewayRoute){RouteDefinition definition=handleData(gatewayRoute);routeDefinitionWriter.save(Mono.just(definition)).subscribe();this.publisher.publishEvent(new RefreshRoutesEvent(this));}public void update(GatewayRoute gatewayRoute) {RouteDefinition definition=handleData(gatewayRoute);try {this.routeDefinitionWriter.delete(Mono.just(definition.getId()));routeDefinitionWriter.save(Mono.just(definition)).subscribe();this.publisher.publishEvent(new RefreshRoutesEvent(this));} catch (Exception e) {e.printStackTrace();}}public void deleteRoute(String routeId){routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();this.publisher.publishEvent(new RefreshRoutesEvent(this));}/*** 路由数据转换公共方法* @param gatewayRoute* @return*/private RouteDefinition handleData(GatewayRoute gatewayRoute){RouteDefinition definition = new RouteDefinition();Map<String, String> predicateParams = new HashMap<>(8);PredicateDefinition predicate = new PredicateDefinition();FilterDefinition filterDefinition = new FilterDefinition();Map<String, String> filterParams = new HashMap<>(8);URI uri = null;if(gatewayRoute.getUri().startsWith("http")){//http地址uri = UriComponentsBuilder.fromHttpUrl(gatewayRoute.getUri()).build().toUri();}else{//注册中心uri = UriComponentsBuilder.fromUriString("lb://"+gatewayRoute.getUri()).build().toUri();}definition.setId(gatewayRoute.getServiceId());// 名称是固定的,spring gateway会根据名称找对应的PredicateFactorypredicate.setName("Path");String predicate1 = gatewayRoute.getPredicates();predicateParams.put("pattern",gatewayRoute.getPredicates());predicate.setArgs(predicateParams);// 名称是固定的, 路径去前缀filterDefinition.setName("StripPrefix");// 作用为去前缀 意思就是列入我的实际接口为localhost:8080/ceshi/ceshio2// 那么他就会去掉ceshi 接口变为localhost:8080/ceshio2接口肯定不通,所以// 例如我的地址为/ga/demo/**那么请求的地址也为这个。然后接口会去掉ga,ga即可调通filterParams.put("_genkey_0", gatewayRoute.getFilters().toString());filterDefinition.setArgs(filterParams);definition.setPredicates(Arrays.asList(predicate));definition.setFilters(Arrays.asList(filterDefinition));definition.setUri(uri);definition.setOrder(Integer.parseInt(gatewayRoute.getSort()));System.out.println("definition:" + JSON.toJSONString(definition));return definition;}
package com.lary.gatewaydemo.ceshi.service;import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.util.ArrayList;
import java.util.List;/*** @program: gateway* @description: peizhi* @author: lary* @create: 2021-08-05 15:25*//***将定义好的路由表信息通过此类读写到redis中*/
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {public static final String  GATEWAY_ROUTES = "gateway_routes";@Autowiredprivate RedisTemplate  redisTemplate;//请注意,此方法很重要,从redis取路由信息的方法,官方核心包要用,核心路由功能都是从redis取的@Overridepublic Flux<RouteDefinition> getRouteDefinitions() {System.out.println("===============RedisRouteDefinitionRepository==============");List<RouteDefinition> routeDefinitions = new ArrayList<>();redisTemplate.opsForHash().values(GATEWAY_ROUTES).stream().forEach(routeDefinition -> {routeDefinitions.add(JSON.parseObject(routeDefinition.toString(), RouteDefinition.class));});return Flux.fromIterable(routeDefinitions);}@Overridepublic Mono<Void> save(Mono<RouteDefinition> route) {System.out.println("===============RedisRouteDefinitionRepository---save ==============");return route.flatMap(routeDefinition -> {redisTemplate.opsForHash().put(GATEWAY_ROUTES, routeDefinition.getId(),JSON.toJSONString(routeDefinition));return Mono.empty();});}@Overridepublic Mono<Void> delete(Mono<String> routeId) {System.out.println("===============RedisRouteDefinitionRepository---delete ==============");return routeId.flatMap(id -> {if (redisTemplate.opsForHash().hasKey(GATEWAY_ROUTES, id)) {redisTemplate.opsForHash().delete(GATEWAY_ROUTES, id);return Mono.empty();}return Mono.defer(() -> Mono.error(new NotFoundException("路由文件没有找到: " + routeId)));});}}

配置文件:

eureka:client:service-url:defaultZone: http://127.0.0.1:8040/eurekaserver:port: 8082
spring:application:name: service-gatewaydatasource:driverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.7.34:3306/mx_institute?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghaiusername: meixpassword: Fvjm3JibEgoPuYzfSZePredis:host: 127.0.0.1port: 6379password: 123456database: 1

数据库数据:

CREATE TABLE `gateway_route` (`id` bigint(20) NOT NULL,`route_id` varchar(255) DEFAULT NULL,`uri` varchar(255) NOT NULL,`predicates` varchar(255) NOT NULL,`filters` varchar(255) DEFAULT NULL,`sort` int(11) DEFAULT '0',`remarks` varchar(255) DEFAULT NULL,`create_time` date DEFAULT NULL,`update_time` date DEFAULT NULL,`is_deleted` int(11) DEFAULT '0',`version` int(11) DEFAULT '1',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

总结:如果把服务都写在数据库中,则无法做负载均衡,需要测试,所以目前引用注册中心进行,两个子服务的application-name都是一样即可做到负载均衡

gateway 动态路由相关推荐

  1. Spring Cloud Gateway 动态路由管理,一点都不吹,应该没有比这更好的管理系统了吧

      本文介绍的 Spring Cloud Gateway 动态路由.不比其他博客通篇 copy 的 Gateway 动态路由,直接上干货!!!为你们提供了一套完整的动态路由管理系统.文末附本文全套代码 ...

  2. gateway动态路由_无语!SpringCloud Gateway动态路由之Nacos,我已经讲得很清楚了

    前言 当我们的网关Gateway程序开发完成之后,需要部署到生产环境,这个时候你的程序不能是单点运行的,肯定是多节点启动(独立部署或者docker等容器部署),防止单节点故障导致整个服务不能访问,网关 ...

  3. gateway动态路由_微服务与网关技术(SIA-GateWay)

    一.背景 软件架构,总是在不断的演进中... 把时间退回到二十年之前,当时企业级领域研发主要推崇的还是C/S模式,PB.Delphi这样的开发软件是企业应用开发的主流.随着时间的推移,基于浏览器的B/ ...

  4. gateway动态路由_微服务中的网关技术:Gateway

    技术/杨33 一.Gateway是什么 为微服务提供一种简单有效的统一的API路由管理方式. Gateway是基于WebFlux框架实现的,而WebFlux框架底层使用了高性能的Reactor模式通讯 ...

  5. Nacos + Spring Cloud Gateway动态路由配置

    前言 Nacos最近项目一直在使用,其简单灵活,支持更细粒度的命令空间,分组等为麻烦复杂的环境切换提供了方便:同时也很好支持动态路由的配置,只需要简单的几步即可.在国产的注册中心.配置中心中比较突出, ...

  6. Spring Cloud Gateway动态路由实现

    Gateway上线部署分析 当你的网关程序开发完成之后,需要部署到生产环境,这个时候你的程序不能是单点运行的,肯定是多节点启动(独立部署或者docker等容器部署),防止单节点故障导致整个服务不能访问 ...

  7. gateway动态路由_spring-cloud-gateway简介

    概述 API网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求.如果让客户端直接与各个微服务通信,会有以下的问题: 客户端 ...

  8. gateway动态路由_Java如何用Spring Cloud奇淫小技巧 来使用gateway作为服务网管

    什么是网关 在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计.开发.测试.部署和管理.这时,各个独立部署单元可以用不同的开发测试团队维护,可以使用不同的编程语言和技术平台进行设计, ...

  9. SpringCloud 微服务网关Gateway 动态路由配置

    概述:在上一章节<SpringCloud 微服务网关Gateway介绍及简单路由配置>中我们讲述了Gateway的最简单的路由配置方式.但是其中比较明显的问题就是我们在配置路由服务的地址时 ...

  10. 一. spring cloud gateway集成 spring cloud stream binder kafka,实现“动态路由“刷新与加载之采坑记录

    一.前言 Spring Cloud Stream是用于构建消息驱动的微服务应用程序的框架. 本文主要介绍如何集成 Spring Cloud Stream,以 Kafka发布订阅模式(topic),实现 ...

最新文章

  1. 虚拟机(VMware Workstation Pro)安装多台Linux
  2. 工业级PoE交换机是如何进行工作的?使用中要注意什么?
  3. python中字符串输出乱码怎么解决_Python字符串的encode与decode研究心得乱码问题解决方法(转)...
  4. 从MFC与ATL的男女关系说起
  5. [codeup 1126]看电视
  6. Amber分子动力学模拟
  7. Mysql 日历数据表
  8. Google原生输入法LatinIME词库构建流程分析(一)
  9. java pgm_java - 如何用Java读取PGM图像? - 堆栈内存溢出
  10. 业务流程与组织结构优化
  11. 计算机技能鉴定高级,职业技能鉴定计算机(高级)试题.pdf
  12. npm启动报错Eorror:ENOENT no such file or directory ‘/node-sass/vender‘
  13. 平面直角坐标系中的旋转公式_中考难点,旋转+动点的最值问题的构建
  14. python-mao
  15. “大学教育的目的”-- 芝加哥大学Andrew Abbott教授的演讲
  16. 生物学中的云计算和大数据
  17. 定时多次自动打开关闭网页的bat脚本
  18. SQLite虚表介绍
  19. 美国食品药物管理局证实:心脏医疗设备可被黑客入侵
  20. 站长导航系统源码-修复版

热门文章

  1. matlab 一维 平滑,MATLAB中数据平滑处理
  2. 2021年全球及中国区块链投融资及技术专利情况:中国区块链相关注册企业达到9.36万余家,新增专利15985项 [图]
  3. PR(Premiere)安装插件Aescripts BeatEdit(Beat Edit)后无法打开的解决方案
  4. 前端之图形学-1 数据可视化
  5. java单点登录解决方案_N多系统单点登录,实现、解决方案。四种解决方案
  6. TiDB的设计哲学——Make It Work! Make It Right! Make It Fast!
  7. 计算机输入什么指令关机,电脑自动关机命令是什么
  8. 如何在电脑上实现企业微信多开?
  9. OpenModelica模型导入Simulink运行的方法
  10. After Effect CC 2019插件