В настоящее время я использую проект весеннего облачного шлюза для создания простого шлюза api, план состоял в том, чтобы сохранить маршрут в mongodb, а затем обновить его, чтобы новый маршрут был доступен. Я сделал что-то простое, чтобы получить свой маршрут от монго.
@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();
}
Мне удалось создать новый маршрут в базе данных, но я не могу обновляться на лету.
Мне нужно понять, как обновлять маршруты на лету.
Спасибо




Я быстро перешел к репо и открытым выпускам.
И кажется, что на данный момент единственный способ обновить маршруты - это использовать Actuator через:
/actuator/gateway/refresh
Вы можете проверить обсуждение здесь: https://github.com/spring-cloud/spring-cloud-gateway/issues/43
Можете ли вы использовать Консул для сохранения определений вашего маршрута вместо mongo. Затем простой вызов POST для обновления привода перезагрузит определения вашего маршрута на лету.
Всякий раз, когда вы хотите обновить маршруты динамически, отправьте 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
SCG (Spring Cloud Gateway) предоставлен RouteDefinitionRepository, вы можете написать свой собственный 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
ЗАПИСЬ http: // ip: порт / привод / шлюз / обновление
@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();
}
}
Здравствуйте, могу я спросить, как добавить RouteConfigDao в мой класс? Это не типа от SCG, не так ли?