Spring Cloud Gateway + Nacos 实现动态路由

1、maven 依赖

主要依赖
		<!-- 网关 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
案件差不多完整主要依赖
		<!--Spring boot 依赖(微服务基础)--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><!--使用exclusions标签来标明要排除的包--><!--排除logback--><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!--Web 服务相关--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 生成配置元数据,比如你平常在yml文件里面配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!--单元测试依赖,子工程中需要单元测试时,不需要再次引入此依赖了--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><!--bootstrap 相关--><!--SpringBoot2.4.x之后默认不加载bootstrap.yml文件,需要在pom里加上依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>4.0.0</version></dependency><!--服务的注册和发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--lombok 依赖,子工程中假如需要lombok,不需要再引入--><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version><scope>provided</scope></dependency><!-- 网关 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>

2、bootstrap.yml配置

server:port: 9999tomcat:max-http-form-post-size: -1max-threads: 500min-spare-threads: 50servlet:context-path: /
spring:main:web-application-type: reactive#当遇到同样名字的时候,是否允许覆盖注册allow-bean-definition-overriding: true profiles:active: ${SYS_ENV:} # local:本地,dev:测试,uat:uatapplication:name: gateway-servicecloud:nacos:# 配置中心#config:username: ${NACOS_USER:nacos}password: ${NACOS_PASSWORD:nacos}server-addr: ${NACOS_IP:nacos.com}:${NACOS_POST:8848}namespace: ${NACOS_NAMESPACE:}file-extension: ymlrefresh-enabled: trueoverride-none: true  #本地配置优先shared-configs:- application.${spring.cloud.nacos.config.file-extension} # 配置文件名-Data Id# 路由网关配置gateway:# 启用了自动根据服务名建立路由discovery:locator:enabled: truelower-case-service-id: true# 动态路由配置
config:# 动态gateway-route:# nacos 配置dataIddataId: gateway-router# nacos服务地址server-addr: ${spring.cloud.nacos.config.server-addr}# 命名空间namespace: ${spring.cloud.nacos.config.namespace}

3、nacos 中心网关路由配置

nacos -  网关路由 配置截图

[{"id": "auth-service","uri": "lb://auth-service","predicates": [{"args": {"pattern": "/auth-service/**"},"name": "Path"}],"filters": [{"args": {"parts": 1},"name": "StripPrefix"}],"order": 1},{"id": "user-service","uri": "lb://user-service","predicates": [{"args": {"pattern": "/user-service/**"},"name": "Path"}],"filters": [{"args": {"parts": 1},"name": "StripPrefix"}],"order": 2}
]

4、配置文件 GatewayRouteConfig

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;/*** 类描述:通过Nacos的配置动态更新网管路由* <pre>*     ApplicationEventPublisherAware 是由 Spring 提供的用于为 Service 注入 ApplicationEventPublisher 事件发布器的接口,使用这个接口,*     我们自己的 Service 就拥有了发布事件的能力。用户注册后,不再是显示地调用其他的业务 Service,而是发布一个用户注册事件。* </pre>**/
@Slf4j
@RefreshScope
@Component
public class GatewayRouteConfig implements ApplicationEventPublisherAware {/** 常量 */private static final String PROPERTIES_SERVER_ADDR = "serverAddr";private static final String PROPERTIES_NAMESPACE = "namespace";private static final String PROPERTIES_GROUP = "group";/** nacos 配置dataId */@Value("${config.gateway-route.dataId:gateway-router}")private String dataId = "gateway-routes";/** nacos 配置group */@Value("${config.gateway-route.group:DEFAULT_GROUP}")private String group = "DEFAULT_GROUP";/** nacos 配置地址 */@Value("${config.gateway-route.server-addr}")private String serverAddr;/** nacos 命名空间 */@Value("${config.gateway-route.namespace}")private String namespace;/** 已加载的路由id集合 */private static final List<String> ROUTE_LIST = new ArrayList<>();private final RouteDefinitionWriter routeDefinitionWriter;/** 事件发布器 */private ApplicationEventPublisher applicationEventPublisher;/*** 方法描述: 构造函数** @param routeDefinitionWriter 路由定义写对象*/public GatewayRouteConfig(RouteDefinitionWriter routeDefinitionWriter) {this.routeDefinitionWriter = routeDefinitionWriter;}@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}/*** 方法描述: 从Nacos的配置中加载动态路由**/@PostConstructpublic void loadRouteFromNacosAndListener() {try {ConfigService configService = NacosFactory.createConfigService(getProperties());// 程序启动时调用Nacos的配置进行路由加载String initConfigInfo = configService.getConfig(dataId, group, 5000);addRouteAndPublish(initConfigInfo);// 添加监听路由变化addListener(configService);} catch (NacosException e) {log.error("加载路由配置错误,详情:", e);}}/*** 方法描述: 添加监听** @param cs 配置服务对象*/private void addListener(ConfigService cs) throws NacosException {// 添加监听cs.addListener(dataId, group, new Listener() {@Overridepublic void receiveConfigInfo(String configInfo) {// 将监听到的路由加载到路由定义器中addRouteAndPublish(configInfo);}@Overridepublic Executor getExecutor() {return null;}});}/*** 方法描述: Nacos配置属性** @return {@link Properties}*/private Properties getProperties() {Assert.notBlank(serverAddr, "Nacos的服务地址为空了!");Properties properties = new Properties();properties.put(PROPERTIES_SERVER_ADDR, serverAddr);if (StrUtil.isNotBlank(namespace)) {properties.put(PROPERTIES_NAMESPACE, namespace);}if (StrUtil.isNotBlank(group)) {properties.put(PROPERTIES_GROUP, group);}return properties;}/*** 添加并发布配置的路由** @param configInfo 路由配置字符串;格式:JSON数组*/private void addRouteAndPublish(String configInfo) {// 加载前需要清空有存在的路由clearRoute();// 解析从Nacos配置中读取的路由配置信息List<RouteDefinition> gatewayRouteDefinitions = JSONObject.parseArray(configInfo, RouteDefinition.class);for (RouteDefinition routeDefinition : gatewayRouteDefinitions) {// 将路由写到定义器中routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();// 将路由id加入内存集合中ROUTE_LIST.add(routeDefinition.getId());}// 刷新路由定义器this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this.routeDefinitionWriter));}/*** 方法描述: 清空已存在的路由*/private void clearRoute() {ROUTE_LIST.forEach(id -> this.routeDefinitionWriter.delete(Mono.just(id)).subscribe());ROUTE_LIST.clear();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/310709.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 5.9.4 转 Qt 6.6.1 遇到的问题总结(一)

最近公司对大家的开发的硬件环境进行了升级&#xff0c;电脑主机的配置、显示器&#xff08;两台大屏显示器&#xff09;变得的逼格高多了。既然电脑上的开发环境都需要重装&#xff0c;就打算把开发环境也升级到最新版本&#xff0c;要用就用最新版本。下面对升级后的开发环境…

10 款顶级的免费U盘数据恢复软件(2024 年 更新)

你曾经遇到过U盘无法访问的情况吗&#xff1f;现在我们教你如何恢复数据。 在信息时代&#xff0c;数据丢失往往会造成巨大的困扰。而USB闪存驱动器作为我们常用的数据存储设备&#xff0c;其重要性不言而喻。但是&#xff0c;U盘也可能会出现各种问题&#xff0c;如无法访问、…

C语言-第十七周做题总结-数组2

id&#xff1a;464 A.求矩阵各行元素之和 题目描述 本题要求编写程序&#xff0c;求一个给定的mn矩阵各行元素之和。 输入 输入第一行给出两个正整数m和n&#xff08;1≤m, n≤6&#xff09;。随后m行&#xff0c;每行给出n个整数&#xff0c;其间以空格分隔。 输出 每行…

3DV 2024 Oral | SlimmeRF:可动态压缩辐射场,实现模型大小和建模精度的灵活权衡

目前大多数NeRF模型要么通过使用大型模型来实现高精度&#xff0c;要么通过牺牲精度来节省内存资源。这使得任何单一模型的适用范围受到局限&#xff0c;因为高精度模型可能无法适应低内存设备&#xff0c;而内存高效模型可能无法满足高质量要求。为此&#xff0c;本文研究者提…

游戏任务系统实现思路

文章目录 一、需求介绍二、数据库设计3、代码部分实现 一、需求介绍 1、首先任务的类型不同&#xff0c;可以分为&#xff1a;日常任务、成长任务、活动任务等等。 2、当达到任务目标时&#xff0c;自动发放任务奖励。 3、任务需要后台可配置&#xff0c;例如&#xff1a;任务…

前馈神经网络复习

习题4-1 对于一个神经元(wx b),并使用梯度下降优化参数w时如果输入x 恒大于0,其收敛速度会比零均值化的输入更慢 在全连接网络模型中&#xff0c;将输入的x值进行零均值化是一种预处理方法&#xff0c;旨在将训练集中的每个输入值x减去其均值&#xff0c;以0为中心&#xff0…

用IDEA创建/同步到gitee(码云)远程仓库(保姆级详细)

前言&#xff1a; 笔者最近在学习java&#xff0c;最开始在用很笨的方法&#xff1a;先克隆远程仓库到本地&#xff0c;再把自己练习的代码从本地仓库上传到远程仓库&#xff0c;很是繁琐。后发现可以IDEA只需要做些操作可以直接把代码上传到远程仓库&#xff0c;也在网上搜了些…

Python 下载与安装

1、下载 打开Python官网&#xff1a;Welcome to Python.org 点击下图所示的【Downloads】按钮进入下载页面。 ​ 进入下载页面后下拉至下图位置&#xff0c;选择版本&#xff0c;点击下载按钮下载。 页面会跳转至下一页下载页面&#xff0c;下拉到下图位置&#xff0c;选择…

缓存cache和缓冲buffer的区别

近期被这两个词汇困扰了&#xff0c;感觉有本质的区别&#xff0c;搜了一些资料&#xff0c;整理如下 计算机内部的几个部分图如下 缓存&#xff08;cache&#xff09; https://baike.baidu.com/item/%E7%BC%93%E5%AD%98 提到缓存&#xff08;cache&#xff09;&#xff0c;就…

51单片机项目(25)——基于51单片机电子秒表的protues仿真

1.功能设计 使用51单片机&#xff0c;完成0-59s的计时&#xff0c;并且实时显示在数码管上。使用一个按键控制计时器的启停。 仿真截图如下&#xff1a; 2.模块介绍 独立按键&#xff1a; 独立按键也称为轻触式开关&#xff0c;是一种简单的电气开关设备。它是一种手动操作Sw…

ERD Online更换Licence为最友好的MIT协议

ERD Online一直秉承着开放、灵活、用户友好的理念&#xff0c;为用户提供高品质的服务。我们非常激动地宣布&#xff0c;ERD Online的许可证已经进行了重大更新&#xff0c;将采用MIT&#xff08;麻省理工学院&#xff09;协议&#xff0c;这一变更旨在进一步提升用户体验&…

计算机网络【EPOLL 源码详解】

IO多路复用 在以前&#xff0c;传统的网络编程是多线程模型&#xff0c;一个线程单独处理一个请求。 然而&#xff0c;线程是很昂贵的资源&#xff1a; 线程的创建和销毁成本很高&#xff0c;linux的线程实际上是特殊的进程&#xff1b;因此通常会使用线程池来减少线程创建和…