springcloud gateway动态路由配置
最近在给公司搭建的springcloud gateway框架,每次配置文件修改路由表信息之后就得重启或者重新发布,故采用动态路由的配置功能。看了网上的资料,决定采用redis缓存机制实现。
具体实现思路如下图,后台管理将路由配置缓存到redis中,gateway监听redis的修改事件,配置路由。
一.redis配置
首先先对redis进行配置,找到redis安装目录里的redis.conf文件(没有可以自己新建或者在启动redis服务时,选择其他配置文件),在配置文件中修改这个参数
notify-keyspace-events “Kg”
详细的可以参考
https://www.cnblogs.com/tangxuliang/p/10659439.html
二.Gateway路由配置
1.RouteDefinitionRepository接口
通过实现该接口,实现从 存储器 ( 例如,内存 / Redis / MySQL 等 )读取、保存、删除路由配置。因为每次url匹配到路由都会调用getRouteDefinitions,为了提高效率,路由配置不直接从redis获取,而是从map缓存中获取。
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
List<RouteDefinition> routeDefinitions = new ArrayList<>();
//将map中的路由加到路由配置中
Map<String, RouteDefinition> routeMap= RouteConfig.getRouteMap();
routeMap.forEach((key, route)->{routeDefinitions.add(route);});
return Flux.fromIterable(routeDefinitions);
}
@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return null;
}
@Override
public Mono<Void> delete(Mono<String> routeId) {
return null;
}
}
2.路由配置map
public class RouteConfig {
public static final String REDIS_ROUTE_SOURCE="gatewayroutes";
//存放路由
private static Map<String, RouteDefinition> RouteMap=new HashMap<String,RouteDefinition>();
public static void setRouteMap(Map<String, RouteDefinition> routeMap) {
RouteMap = routeMap;
}
/**
* 添加路由
* @param key
* @param route
*/
public static void addRoute(String key, RouteDefinition route){
RouteMap.put(key,route);
}
/**
* 清空路由
*/
public static void clearRoute(){
RouteMap.clear();
}
public static Map<String, RouteDefinition> getRouteMap() {
return RouteMap;
}
}
三.实现redis监听
1.监听容器
这里我把容器直接配置在了application类中,也可以新建一个类
@SpringBootApplication
public class GiCloudGateway_App
{
public static void main(String[] args)
{
SpringApplication.run(GiCloudGateway_App.class, args);
}
/**
* 配置redis监听容器
* @param connectionFactory
* @return
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}
2.创建监听器RedisMessageListener
该监听器继承KeyspaceEventMessageListener类,该类可以监听所有的键空间通知。
监听到redis中路由的修改后,将路由存到路由map缓存中,并调用publishEvent(new RefreshRoutesEvent(this)),触发RedisRouteDefinitionRepository的getRouteDefinitions方法
@Slf4j
@Component
public class RedisMessageListener extends KeyspaceEventMessageListener {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private ApplicationEventPublisher publisher;
public RedisMessageListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
@Override
public void onMessage(Message message, byte[] pattern) {
//监听redis的改变,若改变的值为GATEWAY_ROUTES,则更新路由map
String changeKey = message.toString();
try {
if (changeKey.contains(RouteConfig.REDIS_ROUTE_SOURCE)) {
//先清空路由
log.info("清空路由");
RouteConfig.clearRoute();
//从redis中获取路由
Map<Object, Object> redisRouteMap = redisTemplate.opsForHash().entries(RouteConfig.REDIS_ROUTE_SOURCE);
redisRouteMap.forEach((key, routeDefinition) -> {
RouteConfig.addRoute(key.toString(), JSON.parseObject(routeDefinition.toString(), RouteDefinition.class));
});
this.publisher.publishEvent(new RefreshRoutesEvent(this));
log.info("路由重置成功");
}
} catch (Exception ex) {
log.error("异常信息:", ex);
}
}
}
上一篇: 修改默认的springboot输出图标
推荐阅读
-
Spring Cloud Gateway的动态路由怎样做?集成Nacos实现很简单
-
vue动态路由配置及路由传参的方式
-
基于Nacos实现Spring Cloud Gateway实现动态路由的方法
-
(springCloud-8 Zuul网关路由的基本配置feign实现接口调用)
-
Spring Cloud Getway 动态配置路由及自定义修改请求内容、请求url、相应内容
-
Nacos+Spring Cloud Gateway动态路由配置
-
Springcloud GateWay网关配置过程图解
-
springcloud-zuul根据请求url动态更新路由表
-
Nacos和Gateway实现动态路由
-
springcloud之动态路由