欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Nacos和Gateway实现动态路由

程序员文章站 2022-08-17 09:28:20
1. 一些简单的源码分析首先我们主要看GatewayAutoConfiguration这个类红框部分主要是解释为什么gateway不需要像zuul那样加个注解就能生效的原因。接着我们可以看到这个类里自动装配了很多的Bean,这时我们可以想想如果我们使用java代码来配置gateway的路由,会创建一个RouteLocator的子类,所以我们首先去看装配RouteLocator Bean的方法。这段代码可以看到有两个方法都装配了RouteLocator的Bean,但是cachedComposite...

gateway实现动态路由主要有两种方式,这里只讲其中一种方式:写一个实现RouteDefinitionRepository接口的类,然后注入到spring当中

@Component
public class CustomRouteDefinitionRepository implements RouteDefinitionRepository, ApplicationEventPublisherAware {

    @Value("${nacos.config.namespace}")
    private String namespace;

    @Value("${nacos.config.server-addr}")
    private String serverAddr;

    @Autowired
    ObjectMapper objectMapper;

    private List<RouteDefinition> routeDefinitionList;

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    /**
     * 在项目启动时从nacos读出配置
     */
    @SneakyThrows
    @PostConstruct
    public void getNacosConfig() {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        ConfigService configService = NacosFactory.createConfigService(properties);
        String json = configService.getConfig("test", "CUSTOME", 30000);
        this.routeDefinitionList = JSON.parseArray(json, RouteDefinition.class);
    }

    /**
     * 监听nacos配置变化,然后更新路由
     * @param json
     */
    @SneakyThrows
    @NacosConfigListener(groupId = "CUSTOME", type = ConfigType.JSON, dataId = "test")
    public void configChangeListener(String json) {
        System.out.println(json);
        System.out.println("发布事件让gateway更新路由");
        this.routeDefinitionList = JSON.parseArray(json, RouteDefinition.class);
        this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
    }

    @SneakyThrows
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        System.out.println("**************");
        System.out.println("getRouteDefinitions");
        System.out.println(routeDefinitionList);
        System.out.println("**************");
        return Flux.fromIterable(routeDefinitionList);
    }

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return null;
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return null;
    }
}

其中实现ApplicationEventPublisherAware这个接口是为了获得ApplicationEventPublisher的对象,用来发送路由更新的事件。

RouteDefinitionRepository接口有三个方法getRouteDefinitions,save, delete。RouteDefinitionRepository接口又继承了RouteDefinitionLocator和RouteDefinitionWriter两个接口。
save和delete是属于RouteDefinitionWriter接口的,用来修改路由的。getRouteDefinitions方法是属于RouteDefinitionLocator接口的,用来获取路由的。由于我把监听nacos配置变化的方法写到了这个类里,所以我就没有重写save和delete这两个方法,直接就在configChangeListener方法里将路由改变了,然后发送路由更新事件,让gateway更新路由,然后会执行该对象的getRouteDefinitions方法来获取新的路由

本文地址:https://blog.csdn.net/qq_28631073/article/details/109338617

相关标签: gateway java