Spring Cloud Gateway——实现路由动态修改
Posted 不去天涯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud Gateway——实现路由动态修改相关的知识,希望对你有一定的参考价值。
动态路由修改
当我们看了Spring Cloud Gateway的示例代码,和一些网上的入门教程之后,会发现大多是Spring Cloud Gateway — 网关基本功能API暴露说道的三种方法:1.本地配置文件;2.java代码builder.routes().route().build(); 3.服务自动发现。
服务自动发现方法能够做到后端服务ip变化时自动更新,能够做到上游服务的动态。另外两种方式都是纯静态,需要重新启动网关服务修改才能生效。
上述方式都不能完全满足生产需要,一般来说作为生产上的通用网关要求有路由动态修改能力,不重启网关服务即可即使生效。无论是新增路由、或者是修改路由的过滤规则,添加过滤器都可以不重启网关生效。
内置的动态路由
Spring Cloud Gateway内置了一个动态路由类InMemoryRouteDefinitionRepository
。这是一个使用内存存储路由的类,支持acurator接口对路由进行增删改查,但是当网关重启之后所有的内存路由都会消失,也就是说它没有持久化能力。
虽然InMemoryRouteDefinitionRepository
没有达到生产级动态路由修改的需求,但是它提供了一种思路,起到了示例作用。如果需要实现自己的可持久化动态路由,可以仿照InMemoryRouteDefinitionRepository
的路由解析加载能力,以及更新方式实现在即的动态路由。
基于分布式配置的动态路由
基于分布式配置可能是一种最简单便捷的路由动态修改能力了,这里展示基于spring cloud config实现Spring Cloud Gateway动态路由修改。
/**
* a route definition locator, that locate route definition from remote config server or local properties file.
* route definition is json value, not yaml value, e.g.
* "route-definitions=[\\"id\\": \\"websocket_test\\",\\"uri\\": \\"ws://localhost:9000\\",\\"order\\": 9000,\\"predicates\\":[\\"Path=/echo\\"],\\"filters\\":[\\"AddRequestHeader=x-tt-token, 123456\\"]]"
* or
* "route-definitions=[\\"id\\": \\"websocket_test\\",\\"uri\\": \\"ws://localhost:9000\\",\\"order\\": 9000,\\"predicates\\":[\\"name\\":\\"Path\\", \\"args\\":\\"_genkey_0\\":\\"/echo\\"],\\"filters\\":[\\"name\\":\\"AddRequestHeader\\", \\"args\\":\\"_genkey_0\\":\\"x-tt-token\\",\\"_genkey_1\\":\\"123456\\"]]"
*
* compare to spring cloud gateway's default InMemoryRouteDefinitionRepository, route definitions could be loaded when program's startup.
*
* to do this, there is another way. define a bean and load remote route definitions to InMemoryRouteDefinitionRepository when program's startup.
* otherwise, you should implement ApplicationListener<ApplicationEvent>. when refresh event emited, remote route definitions should be reloaded
* into InMemoryRouteDefinitionRepository.
*/
public class ConfigServerRouteDefinitionLocator implements RouteDefinitionLocator
@Value("$route-definitions")
private String routeDefinitions;//a json string, contains route definition lists
@Override
public Flux<RouteDefinition> getRouteDefinitions()
ObjectMapper mapper = new ObjectMapper();
List<RouteDefinition> rdList = null;
try
System.out.println(routeDefinitions);
rdList = mapper.readValue(routeDefinitions, new TypeReference<List<RouteDefinition>>() );
return Flux.fromArray(rdList.toArray(new RouteDefinition[]));
catch (JsonProcessingException e)
e.printStackTrace();
return Flux.empty();
方法很简单,只需要在config server里增加一个路由的配置项即可。config server可以调用Spring Cloud Gateway的路由更新接口/refresh
,路由配置就会自动更新。
如果要实现更复杂的控制逻辑,比如路由配置的路由校验、版本控制、灰度发布等其他功能,可以在定义自己的refresh接口和管理后台进行控制。
其他方式
如果时间允许,可以使用其他存储方式实现路由动态修改能力。可以参考以下文章:
基于Redis实现动态路由修改
基于Redis实现动态路由修改-其中的金丝雀是对上游的金丝雀发布,不是对网关自身的金丝雀控制,这种用法一般不太常见
以上是关于Spring Cloud Gateway——实现路由动态修改的主要内容,如果未能解决你的问题,请参考以下文章
Spirng Cloud Gateway中通过Spring security + WebFlux 实现权限认证