栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

GateWay 动态路由(从nacos上取)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

GateWay 动态路由(从nacos上取)

动态路由的好处

网关动态路可以从redis中取,或者nacos都可以。好处有:修了配置能够动态更新

依赖
    
        
            org.springframework.boot
            spring-boot-starter
        

        
            org.springframework.cloud
            spring-cloud-starter-gateway
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
        

        
            com.alibaba
            fastjson
            1.2.47
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.projectlombok
            lombok
            1.18.10
            true
        
        
            cn.hutool
            hutool-all
            5.4.7
        
    


    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Hoxton.SR9
                pom
                import
            
            
                com.alibaba.cloud
                spring-cloud-alibaba-dependencies
                2.2.6.RELEASE
                pom
                import
            
        
    

配置类

这里可以从nacos注入,我是直接写死了

@Configuration
public class DynamicRouteConfig {
    public static final String NACOS_SERVICE_ADDR="localhost:8848";
    public static final String NACOS_SERVICE_NAMESPACE="7990000d-2835-42d9-86a6-76d998d8c5ea";
    public static final String NACOS_ROUTE_DATA_ID="route.json";
    public static final String NACOS_SROUTE_GROUP="DEFAULT_GROUP";
}
监听类与初始化
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.List;

@Service
@Slf4j
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
    @Resource
    private RouteDefinitionWriter routeDefinitionWriter;
    @Resource
    private RouteDefinitionLocator routeDefinitionLocator;

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

    public void delete(String id){
        try {
            log.info("gateway delete route id {}",id);
            this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
            this.publisher.publishEvent(new RefreshRoutesEvent(this));
        }catch (Exception e){

        }
    }

    public void updateList(List definitions){
        log.info("gateway update route {}",definitions);
        List routeDefinitionsExits = routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
        if (!CollectionUtils.isEmpty(routeDefinitionsExits)){
            routeDefinitionsExits.forEach(routeDefinition ->{
                log.info("delete routeDefinition:{}",routeDefinition);
                delete(routeDefinition.getId());
            });
        }
        definitions.forEach(this::updateById);

    }

    private void updateById(RouteDefinition definition) {
        try {
            log.info("gateway update route {}",definition);
            this.routeDefinitionWriter.delete(Mono.just(definition.getId()));

        }catch (Exception e) {
            definition.getId();
            return;
        }
        try{
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            this.publisher.publishEvent(new RefreshRoutesEvent(this));

        }catch (Exception e){

        }
    }

    public String addRoute(RouteDefinition definition){
        log.info("gateway add route {}",definition);
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        return "success";
    }

}

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;

@Component
@Slf4j
@DependsOn("dynamicRouteConfig")
public class DynamicRouteServiceImolByNacos {
    @Resource
    private DynamicRouteServiceImpl dynamicRouteService;

    private ConfigService configService;


    @PostConstruct
    public void init(){
        log.info("gateway route init......");
        try {
            configService=initConfigService();
            if (configService == null){
                log.info("gateway initConfigService fail");
                return;
            }
            String configInfo = configService.getConfig(DynamicRouteConfig.NACOS_ROUTE_DATA_ID,
                    DynamicRouteConfig.NACOS_SROUTE_GROUP, 3000);
            if (StringUtils.isEmpty(configInfo)) {
              throw  new RuntimeException("ddd");
            }
            log.info("获取网关配置:rn{}",configInfo);
            List definitionList = JSON.parseArray(configInfo, RouteDefinition.class);

            for (RouteDefinition definition : definitionList) {
                log.info("update route :{}",definition.toString());
                dynamicRouteService.addRoute(definition);
            }
        }catch (Exception e) {
            log.error("初始化网关路由时失败:",e);
        }

        dynamicRouteByNacosListener(DynamicRouteConfig.NACOS_ROUTE_DATA_ID,
                DynamicRouteConfig.NACOS_SROUTE_GROUP);
    }

    private void dynamicRouteByNacosListener(String dataId, String group) {
        try {
            configService.addListener(dataId, group, new Listener() {
                @Override
                public Executor getExecutor() {
                    log.info("getExecutor rn");
                    return null;
                }

                @Override
                public void receiveConfigInfo(String configInfo) {
                    log.info("进行网关更新:nr{}",configInfo);
                    List definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
                    log.info("update route :{}",definitionList.toString());
                    dynamicRouteService.updateList(definitionList);
                }
            });
        } catch (NacosException e) {
            log.error("从nacos 接受动态路由配置出错!!!:",e);
        }
    }

    private ConfigService initConfigService(){
        try {
            Properties properties = new Properties();
            properties.setProperty("serverAddr",DynamicRouteConfig.NACOS_SERVICE_ADDR);
            properties.setProperty("namespace",DynamicRouteConfig.NACOS_SERVICE_NAMESPACE);
            return NacosFactory.createConfigService(properties);
        }catch (Exception e){
            log.error("初始化网关路由时失败:",e);
            return null;
        }
    }

}

效果

当nacos 路由文件修改之后,这里可以监听到。

总结

1-要想真正了解,需要了解Gateway源码。
2-了解一些,SPring 的反应式编程

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/353638.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号