✨ 添加新特性。 动态路由 L1 L2 动态更新, redis pub/sub 事件
This commit is contained in:
1 parent
5a752c4a1f
commit
0ff2e3d774
8 files changed
+61
-102
No files matched your search
+18
-25
@@ -1,36 +1,29 @@
|
||||
特别说明: 为了方便其他群友查阅和工程师定位问题
|
||||
- 以下格式请按要求填写,务必提供回显步骤,修改了什么参数等
|
||||
- 只有图或者只有文字描述,看图识字 | 阅读理解的直接禁止登录私服
|
||||
- 问题范围请局限PigX 现有功能范围内,扩展业务问题属于超纲直接关闭
|
||||
- PigX 使用的组件均为开源组件,去对应组件的issue列表翻翻 可能会有更好的发现
|
||||
|
||||
附录: [提问的艺术](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md)
|
||||
|
||||
> A级 蠢问题:救命啊!我的笔记本电脑不能正常显示了!
|
||||
|
||||
> B级 聪明问题:X.org 6.8.1 的鼠标光标会变形,某牌显卡 MV1005 芯片组。
|
||||
|
||||
> C级 更聪明问题:X.org 6.8.1 的鼠标光标,在某牌显卡 MV1005 芯片组环境下 - 会变形。
|
||||
- 工单支持MD 语法格式化,注意可读性喔
|
||||
- 若问题已经解决,请及时反馈并关闭工单
|
||||
- 问题范围请局限PigX 现有功能范围内,扩展业务问题直接关闭
|
||||
|
||||
---
|
||||
### 环境信息 (*)
|
||||
|
||||
### 版本信息
|
||||
- pigx版本:
|
||||
- 是否二开:
|
||||
- 是否修改包名:
|
||||
|
||||
- pigx版本:
|
||||
- 操作系统:
|
||||
- 是否修改包名:
|
||||
- 此描述属于上述哪个等级:
|
||||
|
||||
|
||||
### 报错信息 (截图/日志)
|
||||
|
||||
```
|
||||
|
||||
这里粘贴代码或者、日志
|
||||
---
|
||||
### 问题描述(*)
|
||||
|
||||
```
|
||||
必须提供日志、截图、回显步骤
|
||||
```
|
||||
|
||||
### 问题描述(回显步骤)
|
||||
|
||||
---
|
||||
### 报错信息
|
||||
|
||||
```
|
||||
必须提供日志、截图、回显步骤
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
+10
@@ -40,6 +40,16 @@ public interface CacheConstants {
|
||||
*/
|
||||
String ROUTE_KEY = "gateway_route_key";
|
||||
|
||||
/**
|
||||
* redis reload 事件
|
||||
*/
|
||||
String ROUTE_REDIS_RELOAD_TOPIC = "gateway_redis_route_reload_topic";
|
||||
|
||||
/**
|
||||
* 内存reload 时间
|
||||
*/
|
||||
String ROUTE_JVM_RELOAD_TOPIC = "gateway_jvm_route_reload_topic";
|
||||
|
||||
/**
|
||||
* 参数缓存
|
||||
*/
|
||||
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.cache;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.connection.Message;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2019-08-16
|
||||
* <p>
|
||||
* redis 消息订阅
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class DynamicRouteCacheListener implements MessageListener {
|
||||
private final RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message, byte[] bytes) {
|
||||
byte[] body = message.getBody();
|
||||
byte[] channel = message.getChannel();
|
||||
String msg = redisTemplate.getStringSerializer().deserialize(body);
|
||||
String topic = redisTemplate.getStringSerializer().deserialize(channel);
|
||||
|
||||
log.info("监听到 {} , 消息内容为 {}", msg, topic);
|
||||
RouteCacheUtil.removeRouteList();
|
||||
}
|
||||
|
||||
}
|
||||
+10
-10
@@ -18,7 +18,9 @@
|
||||
package com.pig4cloud.pigx.common.gateway.configuration;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.gateway.cache.DynamicRouteCacheListener;
|
||||
import com.pig4cloud.pigx.common.gateway.support.RouteCacheHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||
import org.springframework.cloud.gateway.config.PropertiesRouteDefinitionLocator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -34,8 +36,10 @@ import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
* <p>
|
||||
* 动态路由配置类
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@ComponentScan("com.pig4cloud.pigx.common.gateway")
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
public class DynamicRouteAutoConfiguration {
|
||||
/**
|
||||
* 配置文件设置为空
|
||||
@@ -52,21 +56,17 @@ public class DynamicRouteAutoConfiguration {
|
||||
* redis 监听配置
|
||||
*
|
||||
* @param redisConnectionFactory redis 配置
|
||||
* @param cacheListener 业务处理
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory
|
||||
, DynamicRouteCacheListener cacheListener) {
|
||||
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisMessageListenerContainer container
|
||||
= new RedisMessageListenerContainer();
|
||||
container.setConnectionFactory(redisConnectionFactory);
|
||||
container.addMessageListener(cacheListener, topic());
|
||||
container.addMessageListener((message, bytes) -> {
|
||||
log.warn("接收到重新JVM 重新加载路由事件");
|
||||
RouteCacheHolder.removeRouteList();
|
||||
}, new ChannelTopic(CacheConstants.ROUTE_JVM_RELOAD_TOPIC));
|
||||
return container;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ChannelTopic topic() {
|
||||
return new ChannelTopic(CacheConstants.ROUTE_KEY);
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -19,7 +19,6 @@ package com.pig4cloud.pigx.common.gateway.support;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.gateway.cache.RouteCacheUtil;
|
||||
import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -55,7 +54,7 @@ public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {
|
||||
log.info("保存路由信息{}", vo);
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.opsForHash().put(CacheConstants.ROUTE_KEY, r.getId(), vo);
|
||||
redisTemplate.convertAndSend(CacheConstants.ROUTE_KEY, "新增路由信息,网关缓存更新");
|
||||
redisTemplate.convertAndSend(CacheConstants.ROUTE_JVM_RELOAD_TOPIC, "新增路由信息,网关缓存更新");
|
||||
return Mono.empty();
|
||||
});
|
||||
}
|
||||
@@ -67,7 +66,7 @@ public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.opsForHash().delete(CacheConstants.ROUTE_KEY, id);
|
||||
});
|
||||
redisTemplate.convertAndSend(CacheConstants.ROUTE_KEY, "删除路由信息,网关缓存更新");
|
||||
redisTemplate.convertAndSend(CacheConstants.ROUTE_JVM_RELOAD_TOPIC, "删除路由信息,网关缓存更新");
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@@ -83,7 +82,7 @@ public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {
|
||||
*/
|
||||
@Override
|
||||
public Flux<RouteDefinition> getRouteDefinitions() {
|
||||
List<RouteDefinitionVo> routeList = RouteCacheUtil.getRouteList();
|
||||
List<RouteDefinitionVo> routeList = RouteCacheHolder.getRouteList();
|
||||
if (CollUtil.isNotEmpty(routeList)) {
|
||||
log.debug("内存 中路由定义条数: {}, {}", routeList.size(), routeList);
|
||||
return Flux.fromIterable(routeList);
|
||||
@@ -94,7 +93,7 @@ public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {
|
||||
List<RouteDefinitionVo> values = redisTemplate.opsForHash().values(CacheConstants.ROUTE_KEY);
|
||||
log.debug("redis 中路由定义条数: {}, {}", values.size(), values);
|
||||
|
||||
RouteCacheUtil.setRouteList(values);
|
||||
RouteCacheHolder.setRouteList(values);
|
||||
return Flux.fromIterable(values);
|
||||
}
|
||||
}
|
||||
+4
-6
@@ -15,7 +15,7 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.cache;
|
||||
package com.pig4cloud.pigx.common.gateway.support;
|
||||
|
||||
import cn.hutool.cache.Cache;
|
||||
import cn.hutool.cache.CacheUtil;
|
||||
@@ -29,10 +29,10 @@ import java.util.List;
|
||||
* @author lengleng
|
||||
* @date 2019-08-16
|
||||
* <p>
|
||||
* 路由缓存
|
||||
* 路由缓存工具类
|
||||
*/
|
||||
@UtilityClass
|
||||
public class RouteCacheUtil {
|
||||
public class RouteCacheHolder {
|
||||
private Cache<String, RouteDefinitionVo> cache = CacheUtil.newLFUCache(50);
|
||||
|
||||
/**
|
||||
@@ -52,9 +52,7 @@ public class RouteCacheUtil {
|
||||
* @param routeList 缓存列表
|
||||
*/
|
||||
public void setRouteList(List<RouteDefinitionVo> routeList) {
|
||||
routeList.forEach(route -> {
|
||||
cache.put(route.getId(), route);
|
||||
});
|
||||
routeList.forEach(route -> cache.put(route.getId(), route));
|
||||
}
|
||||
|
||||
/**
|
||||
+14
-5
@@ -26,15 +26,16 @@ import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.web.context.WebServerInitializedEvent;
|
||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||
import org.springframework.cloud.gateway.config.PropertiesRouteDefinitionLocator;
|
||||
import org.springframework.cloud.gateway.filter.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.listener.ChannelTopic;
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
@@ -80,12 +81,20 @@ public class DynamicRouteInitRunner {
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置文件设置为空redis 加载的为准
|
||||
* redis 监听配置,监听 gateway_redis_route_reload_topic,重新加载Redis
|
||||
*
|
||||
* @param redisConnectionFactory redis 配置
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator() {
|
||||
return new PropertiesRouteDefinitionLocator(new GatewayProperties());
|
||||
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisMessageListenerContainer container
|
||||
= new RedisMessageListenerContainer();
|
||||
container.setConnectionFactory(redisConnectionFactory);
|
||||
container.addMessageListener((message, bytes) -> {
|
||||
log.warn("接收到重新Redis 重新加载路由事件");
|
||||
initRoute();
|
||||
}, new ChannelTopic(CacheConstants.ROUTE_REDIS_RELOAD_TOPIC));
|
||||
return container;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -156,7 +156,7 @@ public class SysRouteConfServiceImpl extends ServiceImpl<SysRouteConfMapper, Sys
|
||||
log.debug("更新网关路由结束 ");
|
||||
|
||||
this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
redisTemplate.convertAndSend(CacheConstants.ROUTE_KEY, "UPMS路由信息,网关缓存更新");
|
||||
redisTemplate.convertAndSend(CacheConstants.ROUTE_JVM_RELOAD_TOPIC, "UPMS路由信息,网关缓存更新");
|
||||
} catch (Exception e) {
|
||||
log.error("路由配置解析失败", e);
|
||||
// 回滚路由,重新加载即可
|
||||
|
||||
Reference in new issue
Block a user