boot3+JDK17+spring-cloud-gateway:4.0.0+spring-cloud:2022.0.0.0+Nacos2.2.1配置动态路由的网关
项目依赖

配置
# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
# Nacos认证信息
spring.cloud.nacos.config.username=nacos
spring.cloud.nacos.config.password=nacos
spring.cloud.nacos.config.contextPath=/nacos
# 设置配置中心服务端地址
spring.cloud.nacos.config.server-addr=localhost:8848
# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可
spring.cloud.nacos.config.namespace=1c5ae1c6-cac5-40ef-b090-b4e9677ea2aa
# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
spring.application.name=zuul-client
spring.cloud.util.enabled=false
spring.profiles.active=dev
spring.cloud.nacos.discovery.group=cloud-test
spring.cloud.nacos.config.group=cloud-test
spring.cloud.nacos.config.file-extension=properties
# Nacos认证信息
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口
spring.cloud.nacos.discovery.server-addr=localhost:8848
# 注册到 nacos 的指定 namespace,默认为 public
spring.cloud.nacos.discovery.namespace=1c5ae1c6-cac5-40ef-b090-b4e9677ea2aa
#dataId 的完整格式如下:prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置
# ${prefix}-${spring.profiles.active}.${file-extension}
# 数据库连接信息{单数据源}
路由配置
sidecar:
# 异构微服务的IP
ip: 127.0.0.1
# 异构微服务的端口
port: 8060
# 异构微服务的健康检查URL
health-check-url: http://localhost:8060/health.json
spring:
cloud:
gateway:
discovery:
locator:
enabled: true #开启通过服务中心的自动根据 serviceId 创建路由的功能
routes:
- id: ldapsso-client
uri: lb://ldapsso-client
predicates:
- Path=/ldapsso/**
filters:
- StripPrefix=1
- id: service-b
uri: lb://service-b
predicates:
- Path=/service-b/test-service-b/**
filters:
- StripPrefix=1
inetutils:
ignored-interfaces: 'VMware Virtual Ethernet Adapter for VMnet1,VMware Virtual Ethernet Adapter for VMnet8'
nacos:
discovery:
server-addr: localhost:8848
application:
name: zuul-client
management:
endpoint:
health:
show-details: always
server:
port: 28083
启动器
@SpringBootApplication
@EnableDiscoveryClient
public class ZuulApplication {
public static void main(String[] args) {
try {
SpringApplication.run(ZuulApplication.class, args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public InetIPv6Utils inetIPv6Utils() {
InetUtilsProperties properties = new InetUtilsProperties();
return new InetIPv6Utils(properties);
}
@Bean
public InetUtils inetUtils() {
InetUtilsProperties properties = new InetUtilsProperties();
return new InetUtils(properties);
}
}
测试类
@RestController
public class IndexController {
@RequestMapping("/index")
public String getIndex(){
return "Zuul";
}
}
路由更新业务处理
public interface RouteService {
/**
* 更新路由配置
*
* @param routeDefinition
*/
void update(RouteDefinition routeDefinition);
/**
* 添加路由配置
*
* @param routeDefinition
*/
void add(RouteDefinition routeDefinition);
}
@Slf4j
@Service
public class RouteServiceImpl implements RouteService, ApplicationEventPublisherAware {
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
/**
* 事件发布者
*/
private ApplicationEventPublisher publisher;
@Override
public void update(RouteDefinition routeDefinition) {
log.info("更新路由配置项:{}", routeDefinition);
this.routeDefinitionWriter.delete(Mono.just(routeDefinition.getId()));
routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
}
@Override
public void add(RouteDefinition routeDefinition) {
log.info("新增路由配置项:{}", routeDefinition);
routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
动态路由加载
package com.example.zuul.listner;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.common.utils.UuidUtils;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.stereotype.Component;
import java.net.URI;
import java.util.*;
import java.util.concurrent.Executor;
@Component
@Slf4j
public class NacosRefreshConfig {
@Autowired
private RouteService routeService;
@Value("${spring.cloud.nacos.config.server-addr}")
private String nacosAddr;
@Value("${spring.cloud.nacos.config.namespace}")
private String nameSpace;
@Value("${spring.cloud.nacos.config.username}")
private String username;
@Value("${spring.cloud.nacos.config.password}")
private String password;
@PostConstruct
public void initBindListner() throws NacosException {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, nacosAddr);
properties.put(PropertyKeyConst.NAMESPACE, nameSpace);
properties.put(PropertyKeyConst.USERNAME, username);
properties.put(PropertyKeyConst.PASSWORD, password);
ConfigService configService = NacosFactory.createConfigService(properties);
configService.addListener(Constants.CONFIG_FILE_NAME, Constants.CONFIG_FILE_GROUP, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
// 刷新路由
List<RouteDefinition> extracted = extracted(configInfo);
for (RouteDefinition routeDefinition : extracted) {
routeService.update(routeDefinition);
}
}
});
}
private static List<RouteDefinition> extracted(String configInfo) {
List<RouteDefinition> list = new ArrayList<>();
JSONArray jsonObjectArr = JSONArray.parseArray(configInfo);
for (int i = 0; i < jsonObjectArr.size(); i++) {
RouteDefinition routeDefinition = new RouteDefinition();
JSONObject jsonObject = jsonObjectArr.getJSONObject(i);
routeDefinition.setId(StringUtils.defaultIfEmpty(jsonObject.getString("id"), UuidUtils.generateUuid()));
routeDefinition.setUri(URI.create(jsonObject.getString("uri")));
List<PredicateDefinition> predicates = routeDefinition.getPredicates();
JSONArray predicates1 = jsonObject.getJSONArray("predicates");
if (predicates1 != null && predicates1.size() > 1) {
for (int ii = 0; ii < predicates1.size(); ii++) {
Set<Map.Entry<String, Object>> entries = predicates1.getJSONObject(ii).entrySet();
for (Map.Entry<String, Object> entry : entries) {
PredicateDefinition predicateDefinition = new PredicateDefinition();
predicateDefinition.setName(entry.getKey());
Map<String, String> args = predicateDefinition.getArgs();
args.put(entry.getKey(), entry.getValue().toString());
predicates.add(predicateDefinition);
}
}
} else {
Set<Map.Entry<String, Object>> entries = predicates1.getJSONObject(0).entrySet();
for (Map.Entry<String, Object> entry : entries) {
PredicateDefinition predicateDefinition = new PredicateDefinition();
predicateDefinition.setName(entry.getKey());
Map<String, String> args = predicateDefinition.getArgs();
args.put(entry.getKey(), entry.getValue().toString());
predicates.add(predicateDefinition);
}
}
List<FilterDefinition> filters = routeDefinition.getFilters();
JSONArray var6 = jsonObject.getJSONArray("filters");
if (var6 != null && var6.size() > 1) {
for (int ij = 0; ij < var6.size(); ij++) {
Set<Map.Entry<String, Object>> entries = var6.getJSONObject(ij).entrySet();
for (Map.Entry<String, Object> entry : entries) {
FilterDefinition filterDefinition = new FilterDefinition();
filterDefinition.setName(entry.getKey());
Map<String, String> args = filterDefinition.getArgs();
args.put(entry.getKey(), entry.getValue().toString());
filters.add(filterDefinition);
}
}
} else {
Set<Map.Entry<String, Object>> entries = var6.getJSONObject(0).entrySet();
for (Map.Entry<String, Object> entry : entries) {
FilterDefinition filterDefinition = new FilterDefinition();
filterDefinition.setName(entry.getKey());
Map<String, String> args = filterDefinition.getArgs();
args.put(entry.getKey(), entry.getValue().toString());
filters.add(filterDefinition);
}
}
list.add(routeDefinition);
}
return list;
}
@NacosConfigListener(dataId = Constants.CONFIG_FILE_NAME)
public void refresh(String msg) {
log.error("-----------------------");
JSONObject jsonObject = JSONObject.parseObject(msg);
log.error(jsonObject.toJSONString());
}
}
public interface Constants {
String CONFIG_FILE_NAME = "zuul-client";
String CONFIG_FILE_GROUP = "cloud-test";
}
Nacos配置
[
{"id":"ldapsso-client","uri":"lb://ldapsso-client","predicates":[{"Path":"/ldapsso/**"}],"filters":[{"StripPrefix":1}]},
{"id":"baidu","uri":"https://www.baidu.com","predicates":[{"Path":"/baidu/**"}],"filters":[{"StripPrefix":1}]},
{"id":"client","uri":"lb://ldapsso-client","predicates":[{"Path":"/client/**"}],"filters":[{"StripPrefix":1}]}
]

测试动态路由生效

完结====
boot3+JDK17+spring-cloud-gateway:4.0.0+spring-cloud:2022.0.0.0+Nacos2.2.1配置动态路由的网关的更多相关文章
- spring cloud gateway 启动报错,Failed to bind on [0.0.0.0:xxx] bind(..) failed: 权限不够
最近把操作系统迁移到了deepin,不得不说Linux中需要学习的还是有很多的,本地启动网关的时候就遇到一个坑,特此记录一下,报错信息. Caused by: reactor.netty.Channe ...
- api网关揭秘--spring cloud gateway源码解析
要想了解spring cloud gateway的源码,要熟悉spring webflux,我的上篇文章介绍了spring webflux. 1.gateway 和zuul对比 I am the au ...
- 纠错帖:Zuul & Spring Cloud Gateway & Linkerd性能对比 (转载)
纠错帖:Zuul & Spring Cloud Gateway & Linkerd性能对比 Spring Cloud Spring Cloud Spring Cloud Gatew ...
- spring cloud gateway 之限流篇
转载请标明出处: https://www.fangzhipeng.com 本文出自方志朋的博客 在高并发的系统中,往往需要在系统中做限流,一方面是为了防止大量的请求使服务器过载,导致服务不可用,另一方 ...
- 微服务网关实战——Spring Cloud Gateway
导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...
- 微服务网关 Spring Cloud Gateway
1. 为什么是Spring Cloud Gateway 一句话,Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是 ...
- 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探
SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...
- 最全面的改造Zuul网关为Spring Cloud Gateway(包含Zuul核心实现和Spring Cloud Gateway核心实现)
前言: 最近开发了Zuul网关的实现和Spring Cloud Gateway实现,对比Spring Cloud Gateway发现后者性能好支持场景也丰富.在高并发或者复杂的分布式下,后者限流和自定 ...
- Spring Cloud Gateway使用简介
Spring Cloud Gateway是类似Nginx的网关路由代理,有替代原来Spring cloud zuul之意: Spring 5 推出了自己的Spring Cloud Gateway,支持 ...
- Spring Cloud Gateway入坑记
Spring Cloud Gateway入坑记 前提 最近在做老系统的重构,重构完成后新系统中需要引入一个网关服务,作为新系统和老系统接口的适配和代理.之前,很多网关应用使用的是Spring-Clou ...
随机推荐
- Go基于观察者模式实现的订阅/发布
面UCloud的时候问到了这题,下来看了一下是基于观察者模式实现的,仅作记录 /** * @Author: lzw5399 * @Date: 2021/5/20 20:38 * @Desc: 基于观察 ...
- Royal Elementor Addons Pro v1.3.987 + v1.5.0 elementor网页设计元素组件插件下载
Royal Elementor Addons Pro elementor网页设计元素组件插件破解版简介&下载 Royal Elementor Addons Pro Nulled Element ...
- 在linux上Git配置多个SSH-Key
Git配置多个SSH-Key SSH Key 背景 当有多个git账号时,比如: a. 一个gitee,用于公司内部的工作开发: b. 一个github,用于自己进行一些开发活动: c.一个gitla ...
- 架构-初识BFF
引言 晚上公司开了一个技术分享会,主要内容就是公司的项目架构,会中讲解了项目整体架构是BFF架构,就是在微服务之上多加了一层. 除此之外,还讲解了DDD设计思想,主要用于各个业务中台,如订单中台.用户 ...
- CH32V203F6P6-TSSOP20测试之02---点灯成功
一.问题思考 直接用官方提供的例程,为何下载程序后没有什么响应,难道自己设计的电路有什么不妥? 于是,对于电路进行具体分析,结果发现: 第一.官方的BOOT0采用杜邦线连接,在芯片手册好像找不到关于B ...
- 第五章 非对称加密算法--DH--RSA
13.1.DH 非对称算法的基石 仅能用于密钥分配,不能用于加解密数据,一般加密数据用AES 密钥长度:512~1024中的64的整数倍 双方各有自己的密钥对 13.2.RSA 最经典的非对称加密算法 ...
- 解决安装python各种包速度慢问题
# 改用清华镜像库 pip install ******* -i https://pypi.tuna.tsinghua.edu.cn/simple
- uni-app之vuex(一)
如何获取到vuex中data的值 uni-app中内置了 vuex 所以可以直接去使用哈. 在项目的跟目录下 创建文件夹store 在store目录下创建index.js index.js目录如下 i ...
- 小米CR6606,CR6608,CR6609 启用SSH和刷入OpenWRT 23.05.5
上个月极低的价格得到一台CR6606和一台CR6609, 一直没时间研究, 终于趁春节假期把这两个都刷成 OpenWRT 配置说明 CPU: MT7621AT,双核880MHz 内存: NT5CC12 ...
- Linux mint安装外部软件
//更新系统 sudo apt-get update更新ruanjian sudo apt-get upgrade更新系统 //安装浏览器 sudo apt-get install chromium ...