SpringCloud Gateway使用redis实现动态路由

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());
        }
    }
}

你可能感兴趣的:(SpringCloud)