SpringCloud Gateway Nacos动态路由

SpringCloud Gateway作为服务网关,提供了扩展接口从不同数据源加载路由配置。
本文章介绍nacos作为服务网关的配置中心,进行gateway网关路由动态配置、刷新。

引入依赖

<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--配置管理-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <groupId>org.springframework.cloud</groupId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>
        <!--解决bootstrap.yml不生效问题-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
            <scope>provided</scope>
        </dependency>

重写RouteDefinitionRepository

package cn.les.tm.gateway.nacos;

import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;

public class NacosRouteDefinitionRepository implements RouteDefinitionRepository {
    public static final Logger log= LoggerFactory.getLogger(NacosRouteDefinitionRepository.class);
    private static ObjectMapper objectMapper=new ObjectMapper();
    // 更新路由信息需要的
    private ApplicationEventPublisher publisher;

    // nacos 的配置信息
    private NacosConfigProperties nacosConfigProperties;
    private NacosRouteProperties nacosRouteProperties;
    public NacosRouteDefinitionRepository(ApplicationEventPublisher publisher, NacosConfigProperties properties, NacosRouteProperties routeConfig){
        this.publisher=publisher;
        this.nacosConfigProperties=properties;
        this.nacosRouteProperties =routeConfig;
        addNacosListener();
    }
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        try {
            String routeJson=nacosConfigProperties.configServiceInstance().getConfig(nacosRouteProperties.getNacosRouteDataId(), nacosRouteProperties.getNacosRouteGroupId(),5000);
            List<RouteDefinition> routeDefinitionList=objectMapper.readValue(routeJson, new TypeReference<List<RouteDefinition>>() {});
            return Flux.fromIterable(routeDefinitionList);
        } catch (NacosException e) {
            log.error(e.getMessage());
        } catch (JsonMappingException e) {
            log.error(e.getMessage());
        } catch (JsonProcessingException e) {
            log.error(e.getMessage());
        }
        return  Flux.fromIterable(Collections.EMPTY_LIST);
    }

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

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return null;
    }
    private void addNacosListener(){
        try {
            nacosConfigProperties.configServiceInstance().addListener(nacosRouteProperties.getNacosRouteDataId(), nacosRouteProperties.getNacosRouteGroupId(), new Listener() {
                @Override
                public Executor getExecutor() {
                    return null;
                }

                @Override
                public void receiveConfigInfo(String configInfo) {
                 //   log.info("监听到{}-{}变化刷新路由{}", nacosRouteProperties.getNacosRouteDataId(), nacosRouteProperties.getNacosRouteGroupId(),configInfo);
                    publisher.publishEvent(new RefreshRoutesEvent(this));
                }
            });
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
    }
}
package cn.les.tm.gateway.nacos;

import com.alibaba.cloud.nacos.NacosConfigProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class NacosConfig {
    @Autowired
    private ApplicationEventPublisher publisher;
    @Autowired
    private NacosConfigProperties nacosConfigProperties;
    @Autowired
    private NacosRouteProperties nacosRouteProperties;
    @Bean
    public NacosRouteDefinitionRepository nacosRouteDefinitionRepository() {
        return new NacosRouteDefinitionRepository(publisher, nacosConfigProperties,nacosRouteProperties);
    }
}
package cn.les.tm.gateway.nacos;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class NacosRouteProperties {
    @Value("${route.nacos.dataId}")
    String nacosRouteDataId;
    @Value("${route.nacos.group}")
    String nacosRouteGroupId;

    public String getNacosRouteDataId() {
        return nacosRouteDataId;
    }

    public void setNacosRouteDataId(String nacosRouteDataId) {
        this.nacosRouteDataId = nacosRouteDataId;
    }

    public String getNacosRouteGroupId() {
        return nacosRouteGroupId;
    }

    public void setNacosRouteGroupId(String nacosRouteGroupId) {
        this.nacosRouteGroupId = nacosRouteGroupId;
    }

}

路由配置放置在Nacos中

[
  {
    "id": "test",
    "uri": "lb://api-test",
    "order":0,
    "predicates": [
      {
        "args": {
          "pattern": "/api/test/**"
        },
        "name": "Path"
      }
    ],
    "filters": [
      {
        "name": "RewritePath",
        "args": {
          "regexp": "/api/test/(?<segment>.*)",
          "replacement": "/$\\{segment}"
        }
      }
    ]
  }
]

1722855783055.jpg

文章作者: 编程之家
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 编程之家
springcloud gateway
喜欢就支持一下吧