Spring Cloud Gateway-动态路由器实现
1 路由配置的两种方式
-
yml文件配置
yml文件配置可以参照官网的配置方式,精简的配置例子如下:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue完全的例子:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue -
代码
@SpringBootApplication
public class DemogatewayApplication {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/get")
.uri("http://httpbin.org"))
.route("host_route", r -> r.host("*.myhost.org")
.uri("http://httpbin.org"))
.route("rewrite_route", r -> r.host("*.rewrite.org")
.filters(f -> f.rewritePath("/foo/(?<segment>.*)", "/${segment}"))
.uri("http://httpbin.org"))
.route("hystrix_route", r -> r.host("*.hystrix.org")
.filters(f -> f.hystrix(c -> c.setName("slowcmd")))
.uri("http://httpbin.org"))
.route("hystrix_fallback_route", r -> r.host("*.hystrixfallback.org")
.filters(f -> f.hystrix(c -> c.setName("slowcmd").setFallbackUri("forward:/hystrixfallback")))
.uri("http://httpbin.org"))
.route("limit_route", r -> r
.host("*.limited.org").and().path("/anything/**")
.filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter())))
.uri("http://httpbin.org"))
.build();
}
}以编程的方式配置。
以上两种都是将路由写死,没有进行动态的加载。下面来看一下如何动态添加路由器。
2 动态路由
spring cloud gateway的源码版本 2.2.6.RELEASE
动态路由可以通过配置来实现动态的加载。首先来通过源码分析一下路由的初始化过程。
默认是从配置文件加载。这个也是官网的配置。路由的定义最终用 RouteDefinition
类进行封装。项目启动所有的 路由都被加载装配,并且存到了内存中:
添加的数据存储在内存中。在没有用户自定义的情况下会从文件配置中加载和内存中加载。在刚刚启动网关项目的内存总是没有任何路由的定义的。
只要实现RouteDefinitionRepository接口就能自定义加载存储位置了。
如何添加了?在Spring Cloud gateway官网上有现成的接口.
actuator api中包含了gateway的动态添加接口和查询接口:
当然也可以参照 GatewayControllerEndpoint 自己实现
本人比较懒用现成的就可以。结合上面的实现的存储位置就能实现动态的添加路由器了。
注意: 用接口/gateway/routes/{id_route_to_create} (POST)添加完成路由后,你立马调用/actuator/gateway/routes/{id} (GET) 是获取不到刚添加的路由。原因在于路由都是从缓存中获取。添加后需要调用/actuator/gateway/refresh (POST) 清除缓存。这样就能重新加载缓存获取到新加的路由器信息了。