我目前正在使用spring cloud网关项目构建简单的api网关,计划是在mongodb中保留路由,然后刷新,以便新路由可用。我做了一些简单的事情来从mongo获取我的路线。
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder){
List<CreateAPIRequest> apiRequestList = repository.findAll();
RouteLocatorBuilder.Builder routeLocator = builder.routes();
for (CreateAPIRequest request: apiRequestList) {
routeLocator
.route(r-> {
r.path("/"+request.getProxy().getListenPath())
.filters(f->f.stripPrefix(1))
.uri(request.getProxy().getTargetUrl())
});
}
return routeLocator.build();
}
我能够在数据库中创建新路由,但我无法动态刷新。
我需要了解如何动态刷新路线。
由于
答案 0 :(得分:2)
RouteDefinitionRepository
已提供了SCG(Spring Cloud Gateway),您可以编写自己的RouteDefinitionRepository,并实现RouteDefinitionRepository
以覆盖getRouteDefinitions
方法。
您可以参考此类:InMemoryRouteDefinitionRepository
例如:
@Service
public class MongodbDefinitionRepository implements RouteDefinitionRepository {
@Autowired
private RouteConfigDao routeConfigDao;
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
// todo
List<RouteDefinition> routeConfigs = routeConfigDao.findAll();
return Flux.fromIterable(routeConfigs);
}
@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return route.flatMap(routeDefinition -> {
// todo
return Mono.empty();
});
}
@Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id -> {
// todo
int delete = routeConfigDao.delete(routeId);
if (delete > 0) {
return Mono.empty();
}
return Mono.defer(() -> Mono.error(new Exception("delete route definition error, routeId:" + routeId)));
});
}
}
如何即时刷新路线
将此内容放入您的application.yml
management:
endpoints:
web:
exposure:
include: gateway
POST http://ip:port/actuator/gateway/refresh
@Service
public class MyPublishBiz implements ApplicationEventPublisherAware {
protected ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public Mono<Void> refresh() {
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return Mono.empty();
}
}
答案 1 :(得分:1)
每当您希望动态更新路由时,都会发送RefreshRoutesEvent。以下组件实现了事件发送功能。
@Component
public class GatewayRoutesRefresher implements ApplicationEventPublisherAware {
ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
publisher = applicationEventPublisher;
}
public void refreshRoutes() {
publisher.publishEvent(new RefreshRoutesEvent(this));
}
}
以下是显示如何使用上述组件的示例:
@Autowired
GatewayRoutesRefresher gatewayRoutesRefresher;
...
public void buildRoutes() {
// build your routes basing on your db entries then refresh the routes in gateway
...
gatewayRoutesRefresher.refreshRoutes();
}
通过查看以下项目代码,您可以找到更完整的概念图:https://github.com/botorabi/HomieCenter
答案 2 :(得分:0)
我快速回到了回购和开放的问题。
目前似乎刷新路线的唯一方法是从Actuator通过:
/actuator/gateway/refresh
您可以在此处查看讨论:https://github.com/spring-cloud/spring-cloud-gateway/issues/43
答案 3 :(得分:0)
您是否可以使用Consul来保留路由定义而不是mongo。然后,对执行器刷新的简单POST调用将动态重新加载您的路径定义。