这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战。
上篇文章我们介绍了Nacos存储路由配置信息构成动态路由配置的过程,这篇文章我们将实现Nacos的连接,然后读取对应的Data Id,解析其中的路由信息导入到Gateway中,并实现对Data Id的监听,如果有改变我们要及时同步更新到Gateway中,由此形成动态路由的配置。
注册网关事件监听器
Nacos路由定义增删改查
在e-commerce-gateway子模块下创建一个config包,创建DynamicRouteServiceImpl类,实现事件推送Aware,动态更新路由网关Service。(implements ApplicationEventPublicsherAware)
添加RouteDefinitionWriter routeDefinitionWriter、RouteDefinitionLocator routeDefinitionLocator、ApplicationEventPublisher publisher三个属性。
接下来增加几个增删改查方法。
1、增加路由定义方法 addRouteDefinition(RouteDefinition definition)
先保存路由配置并发布,然后发布事件通知给 Gateway, 同步新增的路由定义。
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
复制代码
2、根据路由id删除路由配置方法 deleteById(String id)
先按Id去删除,.subscribe发布通知,然后发布事件通知给 gateway去更新路由定义。
this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "delete success";
复制代码
3、更新路由方法 updateByRouteDefinition(RouteDefinition definition)
更新的实现策略比较简单,先删除然后再新增来实现更新。
4、批量更新路由方法 updateList(List<RouteDefinition> definitions)
先拿到当前Gateway中存储的路由定义,如果当前路由定义为空的话就之间保存就好了,如果不为空你,则需要先清除掉之前所有“旧的”路由定义,然后把更新的路由定义同步到Gateway中。
List<RouteDefinition> routeDefinitionsExits =
routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
routeDefinitionsExits.forEach(rd -> {
log.info("delete route definition: [{}]", rd);
deleteById(rd.getId());
});
}
definitions.forEach(definition -> updateByRouteDefinition(definition));
return "success";
复制代码
连接Nacos、读取并监听Nacos配置信息
config包下创建类DynamicRouteServiceImplByNacos,通过Nacos下发动态路由配置,监听Nacos中路由配置的变更。记得要加上@DependsOn注解,依赖于gatewayConfig。
添加configService、dynamicRouteService两个属性。
1、初始化Naocs Config方法 initConfigService()
设置Nacos地址和命名空间即可访问。
2、监听Nacos下发的动态路由配置信息 dynamicRouteByNacosListener(String dataId,String group)
给Nacos Config客户端增加一个监听器,然后自己提供线程池去操作,当监听器收到配置更新时,去调用之前编写的更新路由配置的接口。
3、Bean容器构造完成后执行 init()
加上@postConstruct注解,这样Bean在容器中构造完成之后会执行。初始化Nacos配置客户端,通过Nacos Config 并指定路由配置路径去获取路由配置,然后将这个configInfo反序列回来并添加到我们的配置中去。最后再设置一个监听器,这样如果Data Id 发生变更也能同步到我们的Gateway里面。
以上就完成了动态路由配置的代码编写。