欢迎访问Spring Cloud中国社区

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

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

xujin · 5月前 · 7128 ·

摘要:本文主要介绍通过Nacos下发路由配置实现Spring Cloud Gateway的动态路由。

1.前言

网关中有两个重要的概念,那就是路由配置和路由规则,路由配置是指配置某请求路径路由到指定的目的地址。而路由规则是指匹配到路由配置之后,再根据路由规则进行转发处理。
Spring Cloud Gateway作为所有请求流量的入口,在实际生产环境中为了保证高可靠和高可用,尽量避免重启,需要实现Spring Cloud Gateway动态路由配置。前面章节介绍了Spring Cloud Gateway提供的两种方法去配置路由规则,但都是在Spring Cloud Gateway启动时候,就将路由配置和规则加载到内存里,无法做到不重启网关就可以动态的对应路由的配置和规则进行增加,修改和删除。本文是基于Spring Cloud Gateway的动态路由实现
基础之上编写,通过Nacos配置服务下发路由配置实现动态路由。

<!-- more -->

2. Spring Cloud Gateway简单的动态路由实现

Spring Cloud Gateway的官方文档并没有讲如何动态配置,查看 Spring Cloud Gateway的源码,发现在org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint类中提供了动态配置的Rest接口,但是需要开启Gateway的端点,而且提供的功能不是很强大。通过参考和GatewayControllerEndpoint相关的代码,可以自己编码实际动态路由配置。
下面通过案例的方式去讲解怎么通Nacos实现Spring Cloud Gateway的动态路由。案例工程如spring-cloud-gateway-nacos所示。

代码地址:https://github.com/SpringCloud/spring-cloud-gateway-nacos

3. 简单动态路由的实现

3.1 新建Maven工程sc-gateway-server

配置主要的核心依赖如代码清单所示:
代码清单: spring-cloud-gateway-nacos/sc-gateway-server/pom.xml

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-gateway</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>com.alibaba.nacos</groupId>
  7. <artifactId>nacos-client</artifactId>
  8. <version>0.4.0</version>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-starter-webflux</artifactId>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-actuator</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>com.alibaba</groupId>
  20. <artifactId>fastjson</artifactId>
  21. <version>1.2.47</version>
  22. </dependency>

3.2 根据Spring Cloud Gateway的路由模型定义数据传输模型

分别创建GatewayRouteDefinition.java, GatewayPredicateDefinition.java, GatewayFilterDefinition.java这三个类。
(1) 创建路由定义模型

  1. public class GatewayRouteDefinition {
  2. //路由的Id
  3. private String id;
  4. //路由断言集合配置
  5. private List<GatewayPredicateDefinition> predicates = new ArrayList<>();
  6. //路由过滤器集合配置
  7. private List<GatewayFilterDefinition> filters = new ArrayList<>();
  8. //路由规则转发的目标uri
  9. private String uri;
  10. //路由执行的顺序
  11. private int order = 0;
  12. //此处省略get和set方法
  13. }

(2)创建过滤器定义模型

  1. public class GatewayFilterDefinition {