欢迎访问我的GitHub
内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;
本篇概览
- 本文是《Spring Cloud Gateway实战》系列的第三篇,前文介绍了多种路由配置方式,它们存在一个共同问题:路由配置变更后必须重启Gateway应用才能生效,聪明的您一下就看出了问题关键:这样不适合生产环境!
- 如何让变动后的路由立即生效,而无需重启应用呢?这就是今天的主题:动态路由
设计思路
- 这里提前将设计思路捋清楚,总的来说就是将配置放在nacos上,写个监听器监听nacos上配置的变化,将变化后的配置更新到Gateway应用的进程内:
- 上述思路体现在代码中就是下面三个类:
- 将操作路由的代码封装到名为RouteOperator的类中,用此类来删除和增加进程内的路由
- 做一个配置类RouteOperatorConfig,可以将RouteOperator作为bean注册在spring环境中
- 监听nacos上的路由配置文件,一旦有变化就取得最新配置,然后调用RouteOperator的方法更新进程内的路由,这些监听nacos配置和调用RouteOperator的代码都放RouteConfigListener类中
- 在本次实战中,一共涉及三个配置文件,其中bootstrap.yml + gateway-dynamic-by-nacos是大家熟悉的经典配置,bootstrap.yml 在本地,里面是nacos的配置,gateway-dynamic-by-nacos在naocs上,里面是整个应用所需的配置(例如服务端口号、数据库等),还有一个配置文件在nacos上,名为gateway-json-routes,是JSON格式的,里面是路由配置,之所以选择JSON格式,是因为JSON比yml格式更易于解析和处理;
- 最终,整个微服务架构如下图所示:
- 思路已清晰,开始编码
源码下载
- 本篇实战中的完整源码可在GitHub下载到,地址和链接信息如下表所示(github.com/zq2599/blog…%EF%BC%9A)
名称 | 链接 | 备注 |
---|---|---|
项目主页 | github.com/zq2599/blog… | 该项目在GitHub上的主页 |
git仓库地址(https) | github.com/zq2599/blog… | 该项目源码的仓库地址,https协议 |
git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
- 这个git项目中有多个文件夹,本篇的源码在spring-cloud-tutorials文件夹下,如下图红框所示:
- spring-cloud-tutorials是父工程,下属多个子工程,今天的实战的代码是gateway-dynamic-by-nacos,如下图所示:
编码
- 新增名为gateway-dynamic-by-nacos的工程,其pom.xml内容如下,注意中文注释的说明:
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
- 配置文件bootstrap.yml,上面只有nacos,可见其他配置信息还是来自naocs:
1 | yml复制代码spring: |
- 负责处理进程内路由配置的类是RouteOperator,如下所示,可见整个配置是字符串类型的,用了Jackson的ObjectMapper进行反序列化(注意,前面的实战中配置文件都是yml格式,但本例中是JSON,稍后在nacos上配置要用JSON格式),然后路由配置的处理主要是RouteDefinitionWriter类型的bean完成的,为了让配置立即生效,还要用applicationEventPublisher发布进程内消息:
1 | java复制代码package com.bolingcavalry.gateway.service; |
- 做一个配置类RouteOperatorConfig.java,将实例化后的RouteOperator注册到spring环境中:
1 | java复制代码package com.bolingcavalry.gateway.config; |
- 最后是nacos的监听类RouteConfigListener,可见关键技术点是ConfigService.addListener,用于添加监听,里面就是配置发生变化后更新路由的逻辑,另外还有很重要的一步:立即调用getConfig方法取得当前配置,刷新当前进程的路由配置:
1 | java复制代码package com.bolingcavalry.gateway.service; |
- RouteConfigListener.java中还有一处要记下来,那就是dataId变量的值gateway-json-routes,这是nacos上配置文件的名字,稍后咱们在nacos上配置的时候会用到
- 最后是平淡无奇的启动类:
1 | java复制代码package com.bolingcavalry.gateway; |
- 编码完成了,接下来在nacos上增加两个配置;
- 第一个配置名为gateway-dynamic-by-nacos,内容如下:
1 | yml复制代码server: |
- 第二个配置名为gateway-json-routes,格式要选择JSON,可见只有一个路由(IP+端口那个),另一个用服务名作为URL的路由先不配上去,稍后用来验证动态增加能不能立即生效:
1 | json复制代码[ |
- 至此,咱们已经完成了开发工作,接下来验证动态路由是否能达到预期效果,我这里用的客户端工具是postman
验证
- 确保nacos、provider-hello、gateway-dynamic-by-nacos等服务全部启动:
- 用postman访问http://127.0.0.1:8086/hello/str,可以正常访问到,证明Gateway应用已经从nacos顺利下载了路由:
- 此时如果用访问http://127.0.0.1:8086/lbtest/str应该会失败,因为nacos上还没有配置这个path的路由,如下图,果然失败了:
- 在nacos上修改配置项gateway-json-routes的内容,增加名为path_route_lb的路由配置,修改后完整的配置如下:
1 | json复制代码[ |
- 点击右下角的发布按钮后,gateway-dynamic-by-nacos应用的控制台立即输出了以下内容,可见监听已经生效:
1 | shell复制代码2021-08-15 19:39:45.883 INFO 18736 --- [-127.0.0.1_8848] c.a.n.client.config.impl.ClientWorker : [fixed-127.0.0.1_8848] [polling-resp] config changed. dataId=gateway-json-routes, group=DEFAULT_GROUP |
- 再用postman发同样请求,这次终于成功了,可见动态路由已经成功:
- 由于依赖了spring-boot-starter-actuator库,并且配置文件中也添加了相关配置,我们还可以查看SpringBoot应用内部的配置情况,用浏览器访问http://localhost:8086/actuator/gateway/routes,可见最新的配置情况,如下图:
- 至此,动态路由的开发和验证已完成,希望这个实用的功能可以给您一些参考,开发出更加灵活实用的网关服务;
你不孤单,欣宸原创一路相伴
欢迎关注公众号:程序员欣宸
微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界…
github.com/zq2599/blog…
本文转载自: 掘金