使用Nacos实现Spring Cloud Zuul的动态路由
authors: 叶志远
一.前言
Nacos是阿里巴巴开源的致力于服务发现与管理、动态配置管理,以及动态DNS服务的中间件,目前已发布至0.5.0版本,除了与Spring Cloud更加紧密结合以外,还丧心病狂地支持JDK11。如果您目前的项目碍于Eureka的性能,而又缺乏成本引进Consul,那么Nacos是您最好的选择。好了,回到正题,在上周许进搞了一个使用Nacos实现Spring Cloud Gateway的动态路由,让我们直观地感受到了Nacos的无缝接入如丝般顺滑,作为Spring Cloud中网关的始祖Zuul,自然也需要这一贴心赋能。
二.Spring Cloud Zuul动态路由实现思路
在社区书籍《重新定义Spring Cloud实战》中第8章4小节,详细剖析了Zuul的路由配置表加载以及刷新原理,其大致思想就是重写SimpleRouteLocator类的locateRoutes()方法,同时实现RefreshableRouteLocator接口,方法体引用父类的doRefresh()方法。在书中使用DB作为配置存放的仓库,如今有更为强大的Nacos,只需要将之前读取DB的逻辑换成读取Nacos即可。美中不足的是,由于Nacos还需进一步完善,目前对Spring Cloud中的事件支持还不是很完美,动态刷新只能依靠Zuul的内部逻辑。
三.具体实现
1.在zuul-server中添加Nacos的配置
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>0.4.0</version>
</dependency>
2.读取Nacos配置信息核心代码
@Component
public class PropertiesAssemble{
public Map<String, ZuulRoute> getProperties() {
Map<String, ZuulRoute> routes = new LinkedHashMap<>();
List<ZuulRouteEntity> results = listenerNacos("zuul-server","zuul_route");
for (ZuulRouteEntity result : results) {
if (StringUtils.isBlank(result.getPath())
/*|| org.apache.commons.lang3.StringUtils.isBlank(result.getUrl())*/) {
continue;
}
ZuulRoute zuulRoute = new ZuulRoute();
try {
BeanUtils.copyProperties(result, zuulRoute);
} catch (Exception e) {
}
routes.put(zuulRoute.getPath(), zuulRoute);
}
return routes;
}
private List<ZuulRouteEntity> listenerNacos (String dataId, String group) {
try {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "localhost:8848");
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfig(dataId, group, 5000);
System.out.println("从Nacos返回的配置:" + content);
//注册Nacos配置更新监听器,用于监听触发
// configService.addListener(dataId, group, new Listener() {
// @Override
// public void receiveConfigInfo(String configInfo) {
// System.out.println("Nacos更新了!");
//
// }
// @Override
// public Executor getExecutor() {
// return null;
// }
// });
return JSONObject.parseArray(content, ZuulRouteEntity.class);
} catch (NacosException e) {
e.printStackTrace();
}
return new ArrayList<>();
}
}
目前的demo写得比较简单,直接将Nacos的默认地址与端口写了进来,Nacos对于配置的管理有两个坐标,一是dataId,二是group,本demo中笔者将其分别命名为"zuul-server","zuul_route"。
3.Zuul动态刷新路由实现
这部分可以查看demo地址:https://github.com/SpringCloud/spring-cloud-zuul-nacos,具体就不赘述。
四.演示
1.从Nacos github地址pull源码,配置环境
这里需要在IDEA中添加启动参数-Dnacos.standalone=true
2.启动Nacos,配置Zuul路由信息
启动Nacos后,在浏览器输入http://localhost:8848/nacos/index.html便会跳转到如下页面: 点击配置列表,单击右侧的+号图标,便可以新增一项配置,由于这里已经添加好了,就直接看信息:
3.启动zuul-server,从Nacos加载路由信息测试
启动Zuul后,console中出现如下信息: 在浏览器输入http://localhost:5555/baidu,出现如下效果,直接跳转到目标地址: 我们现在将Nacos中的配置修改一下,将http://github.com/Lovnx换成http://www.baidu.com,修改后直接发布: 我们会在console看到: 在浏览器输入http://localhost:5555/baidu,出现如下效果: