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

gateway集成nacos实现动态网关

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

gateway集成nacos实现动态网关

1.将gateway注册至nacos

此方法成功后以此类推可以获取监听nacos上的所有配置

spring cloud 版本:Hoxton.SR3
spring boot 版本:2.2.5.RELEASE
spring cloud alibaba版本:2.2.1.RELEASE
–其他版本对应可以自行相关文档对应(手动滑稽)
bootstrap.yml的内容

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      discovery:
        locator:
          lower-case-service-id: true   #忽略服务大小写
          enabled: true             #动态创建路由
    nacos:
      discovery:
        server-addr: 10.165.12.109:8848
        enabled: true
      config:
        file-extension: yaml
        server-addr: 10.165.12.109:8848
server:
  port: 1111

application.yml的内容

polo:
  nacos:
    whiteApiName : "whiteApi"    #这个地方不需要用
    whiteIpName : "whiteIp"        #这个地方不需要用
  gateway:
    dateId: "gateway-service-route"
    group: "DEFAULT_GROUP"

pom.xml的内容

        
            org.springframework.boot
            spring-boot-starter-webflux
        
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        

        
        
            org.springframework.cloud
            spring-cloud-starter-gateway
        
        
            org.springframework.boot
            spring-boot-starter-validation
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        
        
            com.alibaba
            fastjson
        
        
        
            org.projectlombok
            lombok
        


编写一个配置类用来读取目前配置文件yml的内容
@Configuration
public class GatewayConfig {
    public static final long DEFAULT_TIMEOUT = 30000;

    public static String GATEWAY_CONFIG_DATA_ID;

    public static String GATEWAY_CONFIG_GROUP;

    public static String NACOS_SERVER_ADDR;

    @Value("${spring.cloud.nacos.discovery.server-addr}")
    public void setNacosServerAddr(String nacosServerAddr){
        NACOS_SERVER_ADDR = nacosServerAddr;
    }
    @Value("${polo.gateway.dateId}")
    public void setGatewayConfigDataId(String gatewayConfigDataId){
        GATEWAY_CONFIG_DATA_ID = gatewayConfigDataId;
    }
    @Value("${polo.gateway.group}")
    public void setGatewayConfigGroup(String gatewayConfigGroup){
        GATEWAY_CONFIG_GROUP = gatewayConfigGroup;
    }
}
编写一个监听器用来获取监听nacos上面的配置文件,并且更新发布
@Slf4j
@ConditionalOnProperty(value = "spring.cloud.nacos.config.enabled", matchIfMissing = true)
@Component
public class DynamicRouteListener {

    ConfigService configService;

    @Autowired
    RouteDefinitionWriter routeDefinitionWriter;

    @Autowired
    ApplicationEventPublisher applicationEventPublisher;


    @EventListener(ApplicationReadyEvent.class)
    public void createListener(){
        if ((configService =initConfigService()) == null){
            log.error("【configService】为空");
            return;
        }
        try {
            //通过configService使用配置id和group拿到路由文本以及编写监听器事件
            String route =configService.getConfigAndSignListener(GatewayConfig.GATEWAY_CONFIG_DATA_ID,GatewayConfig.GATEWAY_CONFIG_GROUP,10000, new Listener() {
                @Override
                public Executor getExecutor() {
                    return null;
                }

                //监听器监听到配置更新
                @Override
                public void receiveConfigInfo(String s) {
                    log.info("【路由更新】监听到路由更新:{}", s);
                    List list = JsonUtils.toList(s, RouteDefinition.class);
                    list.forEach(definition->{
                        //监听器更新
                        updateDefinition(definition);
                    });
                }
            });
            log.info("现有路由:{}",route);
            //拿到目前的路由并发布
            JsonUtils.toList(route,RouteDefinition.class).forEach( f ->{
                updateDefinition(f);
            });
        } catch (NacosException e) {
            e.printStackTrace();
        }
    }
    private void updateDefinition(RouteDefinition routeDefinition){
        //删除原路由
        try {
            routeDefinitionWriter.delete(Mono.just(routeDefinition.getId()));
        } catch (Exception e) {
            log.error("删除原路由失败");
        }
        //保存并发布新路由
        try {
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
            this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
        } catch (Exception e) {
            log.error("发布路由失败");
            e.printStackTrace();
        }
    }

    
    private ConfigService initConfigService(){
        Properties properties = new Properties();
        properties.setProperty(PropertyKeyConst.SERVER_ADDR,GatewayConfig.NACOS_SERVER_ADDR);
        try {
            return NacosFactory.createConfigService(properties);
        } catch (NacosException e){
            log.error("【ConfigService】初始化失败");
            return null;
        }
    }

}

上面代码大概总结如下:

 

上文中有个工具类也贴在下面

@Slf4j
public class JsonUtils {

   private static ObjectMapper mapper = new ObjectMapper();

   public static  List toList(String jsonData, Class beanType) {
       mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
       JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, beanType);
       try {
           return mapper.readValue(jsonData, javaType);
       } catch (Exception e) {
           log.warn("", e);
       }
       return new ArrayList();
   }
}

启动类也要加上@Enabl
eDiscoveryClient用来连接nscos上注册发现

测试
1.启动nacos:本文用的window版本,在nacos bin目录下,startup.cmd -m standalone 启动,能够进入nacos网站地址说明启动成功
2.启动网关
2.1.1 启动官网时,将会自动注册nacos服务列表

2.1.2 由于我们添加了监听器,启动时就会首先去nacos读取相关配置(先得在nacos配置管理编写与咱们yml名字对应的配置文件),并发布(上面代码有体现)
打印的日志

nacos上面编写的配置(pattern参数多了一个/!)

可以看出和我们的配置一毛一样
配置类容贴上

[{
    "id": "user-center",
    "order": 0,
    "predicates": [{
        "args": {
            "pattern": "user-center/**"
        },
        "name": "Path"
    }],
    "uri": "lb://user-center"
}]

在nacos修改配置并发布,看监听器能否监听并发布

控制成功监听到了


1.网关路由编写是json格式和名字对用RouteDefinition,不然一个字母的错误毁了一个小时
2.各个cloud boot alibaba 版本对应上

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

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

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