首页 > 其他分享 >spring cloud gateway 配置动态路由

spring cloud gateway 配置动态路由

时间:2023-08-07 17:32:30浏览次数:42  
标签:utf8mb4 spring springframework item import org NULL gateway cloud

  1. 在mysql建表存储路由信息
DROP TABLE IF EXISTS `route`;
CREATE TABLE `route`  (
  `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `predicates` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `filters` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `del` tinyint NULL DEFAULT NULL,
  `comment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注释',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of route
-- ----------------------------
INSERT INTO `route` VALUES ('jihua', 'http://127.0.0.1:8090/', '[{\"args\": {\"_genkey_0\": \"/jihua/**\"}, \"name\": \"Path\"}]', '[{\"args\": {\"_genkey_0\": \"1\"}, \"name\": \"StripPrefix\"}]', 0, NULL);
INSERT INTO `route` VALUES ('jihua_mysql', 'http://127.0.0.1:8090/', '[{\"args\": {\"_genkey_0\": \"/jihuamysql/**\"}, \"name\": \"Path\"}]', '[{\"args\": {\"_genkey_0\": \"1\"}, \"name\": \"StripPrefix\"}]', 0, NULL);
INSERT INTO `route` VALUES ('jihua_oracle', 'http://127.0.0.1:8090/', '[{\"args\": {\"_genkey_0\": \"/jihuaoracle/**\"}, \"name\": \"Path\"}]', '[{\"args\": {\"_genkey_0\": \"1\"}, \"name\": \"StripPrefix\"}]', 0, NULL);
  1. mybatis查询路由信息
import com.example.demo.po.Route;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.Set;

@Mapper
public interface RouteDao {

    @Select("select * from route where del=0")
    Set<Route> selectAll();
}
  1. 创建定时任务在项目启动时初始化路由, 和每五分钟读取最新路由信息
import com.example.demo.dao.RouteDao;
import com.example.demo.po.Route;
import com.example.demo.util.JsonUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
@EnableScheduling
public class DynamicRouteService implements ApplicationEventPublisherAware {
    @Autowired
    private RouteDefinitionRepository routeDefinitionRepository;
    @Autowired
    private RouteDao routeDao;
    private ApplicationEventPublisher publisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }

    private Set<Route> oldRouteSet = Collections.emptySet();

    @Scheduled(fixedDelay = 5 * 60 * 1000)
    void refreshRouteTask() {
        refreshRoute();
    }

    /**
     * 从数据库读取路由配置,并刷新网关路由信息
     */
    void refreshRoute() {
        Set<Route> newestRouteSet = routeDao.selectAll();
        boolean routeChangeFlag = false;
        for (Route item : newestRouteSet) {
            if (!oldRouteSet.contains(item)) {
                try {
                    log.info("新增路由: {}", JsonUtil.writeValueAsString(item));
                    RouteDefinition routeDefinition = new RouteDefinition();
                    routeDefinition.setId(item.getId());
                    routeDefinition.setUri(new URI(item.getUri()));
                    routeDefinition.setPredicates(JsonUtil.readValue(item.getPredicates(), new TypeReference<List<PredicateDefinition>>() {
                    }));
                    routeDefinition.setFilters(JsonUtil.readValue(item.getFilters(), new TypeReference<List<FilterDefinition>>() {
                    }));
                    routeDefinitionRepository.save(Mono.just(routeDefinition)).subscribe();
                    routeChangeFlag = true;
                } catch (Exception e) {
                    log.error("新增路由异常", e);
                }
            }
        }
        for (Route item : oldRouteSet) {
            if (!newestRouteSet.contains(item)) {
                routeDefinitionRepository.delete(Mono.just(item.getId())).subscribe();
                routeChangeFlag = true;
                log.info("删除路由: {}", JsonUtil.writeValueAsString(item));
            }
        }
        if (routeChangeFlag) {
            oldRouteSet = newestRouteSet;
            publisher.publishEvent(new RefreshRoutesEvent(this));
        }

    }
}

标签:utf8mb4,spring,springframework,item,import,org,NULL,gateway,cloud
From: https://blog.51cto.com/u_14583021/6995786

相关文章

  • Spring—ObjectProvider更加宽泛的依赖注入
    1.Spring依赖注入在Spring4.3之后,引入了一个新特性:当构造方法只有一个参数时,可以不使用@Autowired注解。@ServicepublicclassFooService{privateFooRepositoryfooRepository;publicFooService(FooRepositoryfooRepository){this.fooRepository=foo......
  • springboot智能3D导诊系统源码,基于规则模板的开发原理
    互联网智慧3D导诊系统源码通过智能导诊,进行自助问询及挂号服务,减轻导诊台护士压力,挂号更加方便快捷。技术架构:springboot+redis+mybatisplus+mysql+RocketMQ  智慧导诊系统开发原理导诊系统从原理上大致可分为基于规则模板和基于数据模型两类。1、基于规则推理的方法通过人工建......
  • Spring记录-01
    一、Spring三种思想1.loc思想:InversionofControl,控制反转,强调是在原来程序中创建中创建Bean的权利反转给第三方2.Dl思想:DependencyInjection,依赖注入,强调Bean之间的关系,这种关系由第三方去负责并管理3.AOP思想:AspectOrientedProgramming,面向切面编程,功能的横向抽取,主......
  • Springboot-Mybatis(idea)-自学笔记
    Spring-boot-Mybaties快速入门使用Mybatis查询所有用户数据准备工作(创建springboot工程,数据库表格user,实体类User)引入Mybatis的相关依赖,配置Mybatis(数据库连接信息)编写SQL语句(注解/XML)单元测试packagecom.example;importcom.example.mapper.UserMapper;impo......
  • SpringBoot3基础用法
    技术和工具「!喜新厌旧」一、背景最近在一个轻量级的服务中,尝试了最新的技术和工具选型;即SpringBoot3,JDK17,IDEA2023,Navicat16,虽然新的技术和工具都更加强大和高效,但是适应采坑的过程总是枯燥的;【环境一览】首先框架主体从SpringBoot2升级到SpringBoot3,Java基础环境从JDK8升......
  • Spring Boot是什么?它的优缺点以及核心
    一、SpringBoot是什么?SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域(rapidapplicationd......
  • SpringBoot3基础用法
    目录一、背景二、环境搭建1、工程结构2、框架依赖3、环境配置三、入门案例1、测试接口2、全局异常3、日志打印3.1日志配置3.2日志打印四、打包运行五、参考源码技术和工具「!喜新厌旧」一、背景最近在一个轻量级的服务中,尝试了最新的技术和工具选型;即SpringBoot3,JDK17,IDEA......
  • SpringBoot Netty socket使用
    SpringBootNettysocket使用Netty是由JBOSS提供的一个java开源框架,现为Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。这里springBoot整合起来使用测试,性能怎么的不怎么了解,至少能用maven引用依......
  • 如何解决Spring循环依赖?
    在Spring中,循环依赖指的是两个或多个Bean之间相互依赖,形成一个闭环,导致Spring容器无法正确地创建这些Bean。解决Spring循环依赖的方法是通过Spring容器的三个阶段来处理:实例化、属性注入、和初始化。为了更好地解释,我们假设有两个类A和B相互依赖。A依赖于B,B也依赖于A。以下是解决循......
  • Spring Boot 最佳实践
    本文翻译自国外论坛medium,原文地址:https://medium.com/@raviyasas/spring-boot-best-practices-for-developers-3f3bdffa0090SpringBoot是一种广泛使用且非常流行的企业级高性能框架。以下是一些最佳实践和一些技巧,我们可以使用它们来改进SpringBoot应用程序并使其更加高效......