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 ...
随机推荐
- 循规蹈矩--从零开始建设k8s监控(一)
前言 监控k8s集群,目前主流就是使用prometheus以及其周围的生态,本文开始介绍怎么一步步完成k8s监控的建设 环境准备 组件 版本 操作系统 Ubuntu 22.04.4 LTS minik ...
- lottie-web动画库在HTML5页面中和在vue项目中的两种使用方式
本文主要介绍lottie-web动画库在HTML5页面中和在vue项目中的两种使用方式. 1.在HTML5页面中的使用方式 具体使用步骤详见下面的代码: <!DOCTYPE html> & ...
- .Net程序员机会来了,微软官方新推出一个面向Windows开发者本地运行AI模型的开源工具
想要开发AI产品的.Net程序员机会来了,这个项目应该好好研究. 虽然说大模型基本都有提供网络API,但肯定没有直接使用本地模型速度快. 最近微软官方新推出AI Dev Gallery开源项目,可以帮 ...
- 记一次cannot access its superinterface问题的的排查 → 强如Spring也一样写Bug
开心一刻 昨天在幼儿园,领着儿子在办公室跟他班主任聊他的情况 班主任:皓瑟,你跟我聊天是不是紧张呀 儿子:是的,老师 班主任:不用紧张,我虽然是你的班主任,但我也才22岁,你就把我当成班上的女同学 班 ...
- 手把手带你使用Karpenter减少K8s集群资源浪费
Kubernetes 集群的主要成本因素之一是数据平面上的计算层.将 Kubernetes 集群运行在 Amazon EC2 Spot 实例上是一种显著降低计算成本的有效方式.使用 Spot 实例可以 ...
- 单点登录-OAuth2
单点登录的实现原理 单点登录在现在的系统架构中广泛存在,他将多个子系统的认证体系打通,实现了一个入口多处使用,而在架构单点登录时,也会遇到一些小问题,在不同的应用环境中可以采用不同的单点登录实现方案来 ...
- biancheng-Spring Cloud Alibaba Nacos
参考http://c.biancheng.net/springcloud/what-is-alibaba.html http://c.biancheng.net/springcloud/nacos.h ...
- String、StringBuffer、StringBuilder三者的异同
/*String.StringBuffer.StringBuilder三者的异同?String:不可变的字符序列:底层使用char[]存储StringBuffer:可变的字符序列:线程安全的,效率低: ...
- PayDay Intermediate
nmap + dirsearch 发现web站点 扫目录 ┌──(root㉿kali)-[/home/ftpuserr] └─# nmap -p- -A 192.168.167.39 Starting ...
- Zabbix 安装报错解析
一.Q:Error connecting to database: Access denied for user 'zabbix' @ 'localhost' to database 'zabbix' ...