API网关服务组件Spring Cloud Zuul使用详解8(路由详解8:动态路由)
作者:hangge | 2020-10-20 08:10
在微服务架构中,由于API 网关服务担负着外部访问统一入口的重任,它同其他应用不同,任何关闭应用和重启应用的操作都会使系统对外服务停止,对于很多 7 * 24 小时服务的系统来说,这样的情况是绝对不被允许的。所以,作为最外部的网关,它必须具备动态更新内部逻辑的能力,比如动态修改路由规则、动态添加/删除过滤器等。
通过 Zuul 实现的 API 网关服务当然也具备了动态路由和动态过滤器的能力。我们可以在不重启 API 网关服务的前提下,为其动态修改路由规则和添加或删除过滤器。本文首先演示如何实现动态路由功能。
十、动态路由
1,实现原理
- 从之前的文中我们可以发现对于路由规则的控制几乎都可以在配置文件 application.properties 或 application.yaml 中完成。
- 因此对于如何实现 Zuul 的动态路由,我们很自然地会将它与 Spring Cloud Config 的动态刷新机制联系到一起。只需将 API 网关服务的配置文件通过 Spring Cloud Config 连接的 Git 仓库存储和管理,我们就能轻松实现动态刷新路由规则的功能。
2,准备工作
(1)首先我们一个连接到 Git 仓库分布式配置中心 config-server 应用。具体的搭建步骤可以参考我之前写的这篇文章:(2)接着在 application.properties 中添加配置服务的基本信息以及 Git 仓库的相关信息:
spring.application.name=config-server
server.port=7001
spring.cloud.config.server.git.uri=https://gitee.com/hangge/hangge.com
spring.cloud.config.server.git.search-paths=config
spring.cloud.config.server.git.username=hangge
spring.cloud.config.server.git.password=123
(3)同时还要在 Git 仓库中增加网关的配置文件,这里取名为 api-gateway.properties。
(4)在该配置文件中,我们为 API 网关服务预定义如下路由规则:
zuul.routes.api-a.path=/api-a/** zuul.routes.api-a.service-id=hello-service zuul.routes.api-b.path=/api-b/** zuul.routes.api-b.service-id=feign-consumer
(5)最后启动配置中心 config-server 应用,访问下 http://localhost:7001/api-gateway/default 可以看到返回相应的配置信息:
注意:由于本文主要介绍 API 网关的使用,所以这里忽略了关于 label 和 profile 的配置,默认会使用 master 分支和 default 配置文件。
3,创建支持动态路由的 API 网关服务
(1)首先创建一个基础的 Spring Boot 工程,命名为 api-gateway。然后在 pom.xml 中引入 zuul、eureka 和 config 依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
(2)接着在 resources 目录下创建配置文件 bootstrap.properties,并在该文件中指定 config-server 和 eureka-server 的具体地址,以获取应用的配置文件和实现服务注册与发现:
注意:最后一个配置是为了后面能通过 /routes 端点接口来查看当前网关上的路由规则,以及 /refresh 端点来刷新配置。
spring.application.name=api-gateway server.port=5556 spring.cloud.config.uri=http://localhost:7001 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ management.endpoints.web.exposure.include=*
(3)接着在应用主类上添加 @EnableZuulProxy 注解开启 Zuul 的 API 服务网关功能,同时还需要使用 @RefreshScope 注解来将 Zuul 的配置内容动态化:
@EnableZuulProxy @SpringBootApplication public class ApiGatewayApplication { public static void main(String[] args) { SpringApplication.run(ApiGatewayApplication.class, args); } @RefreshScope @ConfigurationProperties("zuul") public ZuulProperties zuulProperties() { return new ZuulProperties(); } }
4,运行测试
(1)我们将 config-server、eureka-server、api-gateway 以及配置文件中路由规则指向的具体服务(比如 hello-service)启动起来。此时在 API 网关应用 api-gateway 的控制台中可以看到它输出从 config-server 中获取配置文件过程的日志信息,根据这些信息,可以判断获取配置信息的路径等内容是否正确。
(2)通过调用 API 网关服务的 /routes 接口来获取当前网关上的路由规则,可以看到如下信息:
(3)测试一下网关功能,当有一个请求 http://localhost:5556/api-a/hello 被发送到 API 网关上,根据匹配的规则,API 网关会转发请求到 hello-service 服务上:
(4)上面结果同我们直接请求 hello-servie 服务接口是一样的:
(5)接着测试下动态路由功能。首先就给 Git 仓库中的 api-gateway.properties 文件。这里将 api-a 的路由规则改成物理地址的形式:
zuul.routes.api-a.path=/api-a/** zuul.routes.api-a.service-id=http://localhost:8081/ zuul.routes.api-b.path=/api-b/** zuul.routes.api-b.service-id=feign-consumer
(6)然后通过向 api-gateway 的 /refresh 接口发送 POST 请求来刷新配置信息。当配置文件有修改的时候,该接口会返回被修改的属性名称。
(7)最后我们再次通过 API 网关服务的 /routes 接口来查看当前的所有路由规则,可以看到 api-a 映射目标从原来的 hello-service 服务修改成了物理地址 http://localhost:8081/
全部评论(0)