SpringCloud Gateway使用redis實現動態路由
gateway中默認的路由是存在本地的,如果有自定義的路由策略,路由的拓展性便會收到影響,因此使用考慮使用動態路由來使gateway的路由是無狀態的,經研究發現只需要實現RouteDefinitionRepository就可以自定義路由的存儲策略。
@Component
public class RedisRouteRepositoryComponent implements RouteDefinitionRepository {
private Logger log = LoggerFactory.getLogger(RedisRouteRepositoryComponent.class);
private final String ROUTE = "route";
@Autowired
private RedisComponent redisComponent;
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return route.flatMap(r -> {
log.info("保存路由信息{}", r);
redisComponent.addHashKey(ROUTE, r.getId(), r);
return Mono.empty();
});
}
@Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id -> {
if (redisComponent.hasHashKey(ROUTE,id)) {
log.info("刪除路由信息{}", id);
redisComponent.delHashKey(ROUTE, id);
return Mono.empty();
}
return Mono.defer(() -> Mono.error(
new NotFoundException("RouteDefinition not found: " + routeId)));
});
}
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
Map<String,RouteDefinition> routes;
if(redisComponent.hasKey(ROUTE)){
// redis中拉取路由
log.info("拉取路由信息");
List<RouteDefinition> routeDefinitions = new LinkedList<>();
redisTemplate.opsForHash().values(ROUTE).stream().forEach(routeDefinition -> {
routeDefinitions.add((RouteDefinition) routeDefinition);
});
return Flux.fromIterable(routeDefinitions);
} else {
routes = new LinkedHashMap<>();
redisComponent.addHashMap(ROUTE,routes);
return Flux.fromIterable(routes.values());
}
}
}