本篇概览
- 本文是《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下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
名称 |
链接 |
备注 |
项目主页 |
https://github.com/zq2599/blog_demos |
该项目在GitHub上的主页 |
git仓库地址(https) |
https://github.com/zq2599/blog_demos.git |
该项目源码的仓库地址,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内容如下,注意中文注释的说明:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-tutorials</artifactId>
<groupId>com.bolingcavalry</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway-dynamic-by-nacos</artifactId>
<dependencies>
<dependency>
<groupId>com.bolingcavalry</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>