欢迎访问Spring Cloud中国社区

《重新定义Spring Cloud实战》由Spring Cloud中国社区倾力打造,基于Spring Cloud的Finchley.RELEASE版本,本书内容宽度足够广、深度足够深,而且立足于生产实践,直接从生产实践出发,包含大量生产实践的配置。欢迎加微信Software_King进群答疑,国内谁在使用Spring Cloud?欢迎登记

使用Nacos实现Spring Cloud Zuul的动态路由

Lovnx · 19天前 · 685 ·

一.前言

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的配置
  1. <dependency>
  2. <groupId>com.alibaba.nacos</groupId>
  3. <artifactId>nacos-client</artifactId>
  4. <version>0.4.0</version>
  5. </dependency>
2.读取Nacos配置信息核心代码
  1. @Component
  2. public class PropertiesAssemble{
  3. public Map<String, ZuulRoute> getProperties() {
  4. Map<String, ZuulRoute> routes = new LinkedHashMap<>();
  5. List<ZuulRouteEntity> results = listenerNacos("zuul-server","zuul_route");
  6. for (ZuulRouteEntity result : results) {
  7. if (StringUtils.isBlank(result.getPath())
  8. /*|| org.apache.commons.lang3.StringUtils.isBlank(result.getUrl())*/) {
  9. continue;
  10. }
  11. ZuulRoute zuulRoute = new ZuulRoute();
  12. try {
  13. BeanUtils.copyProperties(result, zuulRoute);
  14. } catch (Exception e) {
  15. }
  16. routes.put(zuulRoute.getPath(), zuulRoute);
  17. }
  18. return routes;
  19. }
  20. private List<ZuulRouteEntity> listenerNacos (String dataId, String group) {
  21. try {
  22. Properties properties = new Properties();
  23. properties.put(PropertyKeyConst.SERVER_ADDR, "localhost:8848");
  24. ConfigService configService = NacosFactory.createConfigService(properties);
  25. String content = configService.getConfig(dataId, group, 5000);
  26. System.out.println("从Nacos返回的配置:" + content);
  27. //注册Nacos配置更新监听器,用于监听触发
  28. // configService.addListener(dataId, group, new Listener() {
  29. // @Override
  30. // public void receiveConfigInfo(String configInfo) {
  31. // System.out.println("Nacos更新了!");
  32. //
  33. // }
  34. // @Override
  35. // public Executor getExecutor() {
  36. // return null;
  37. // }
  38. // });
  39. return JSONObject.parseArray(content, ZuulRouteEntity.class);
  40. } catch (NacosException e) {
  41. e.printStackTrace();
  42. }
  43. return new ArrayList<>();
  44. }
  45. }

目前的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,出现如下效果:
在这里插入图片描述

—————————->>>DEMO源码