gateway网关配合nacos做动态路由

如题所述

第1个回答  2022-07-02
通过gateway配合nacos做动态路由一共两种方式,第一种时通过json,解析json进行动态路由,另一种通过设置properties文件进行路由

gateway的动态路由可以配置在nacos的配置中心上,gateway启动的时候来读取配置,对各个请求进行路由

配置文件如下所示

server:

port:9537

spring:

application:

name: cloud-alibaba-gateway

cloud:

nacos:

discovery:

server-addr: localhost:8848

config:

server-addr: localhost:8848

file-extension: json

group: DEFAULT_GROUP#nacos分组

    gateway:#路由

      discovery:

locator:

enabled:true      #开启从注册中心动态创建路由的功能,利用微服务名进行路由

management:

endpoints:

web:

exposure:

include: cloud-alibaba-gateway

package com.gateway.springcloud.config;

import com.alibaba.fastjson.JSONObject;

import com.alibaba.nacos.api.NacosFactory;

import com.alibaba.nacos.api.PropertyKeyConst;

import com.alibaba.nacos.api.config.ConfigService;

import com.alibaba.nacos.api.config.listener.Listener;

import com.alibaba.nacos.api.exception.NacosException;

import org.springframework.beans.factory.annotation.Autowired;

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

import org.springframework.cloud.context.config.annotation.RefreshScope;

import org.springframework.cloud.gateway.event.RefreshRoutesEvent;

import org.springframework.cloud.gateway.route.RouteDefinition;

import org.springframework.cloud.gateway.route.RouteDefinitionWriter;

import org.springframework.context.ApplicationEventPublisher;

import org.springframework.context.ApplicationEventPublisherAware;

import org.springframework.context.annotation.Configuration;

import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;

import java.util.ArrayList;

import java.util.List;

import java.util.Properties;

import java.util.concurrent.Executor;

/**

* 配置动态路由

*/

@Configuration

public class NacosDynamicRouteServiceimplements ApplicationEventPublisherAware {

private StringdataId ="cloud-alibaba-gateway";

    private Stringgroup ="DEFAULT_GROUP";

    @Value("${spring.cloud.nacos.config.server-addr}")

private StringserverAddr;

    @Autowired

    private RouteDefinitionWriterrouteDefinitionWriter;

    private ApplicationEventPublisherapplicationEventPublisher;

    private static final ListROUTE_LIST =new ArrayList<>();

    @PostConstruct

    public void dynamicRouteByNacosListener() {

try {

Properties properties =new Properties();

            properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);

            ConfigService configService = NacosFactory.createConfigService(properties);

            String config = configService.getConfig(dataId, group, 5000);

            configService.addListener(dataId, group, new Listener() {

@Override

                public void receiveConfigInfo(String configInfo) {

clearRoute();

                    try {

List gatewayRouteDefinitions = JSONObject.parseArray(configInfo, RouteDefinition.class);

                        for (RouteDefinition routeDefinition : gatewayRouteDefinitions) {

addRoute(routeDefinition);

                        }

publish();

                    }catch (Exception e) {

e.printStackTrace();

                    }

}

@Override

                public ExecutorgetExecutor() {

return null;

                }

});

        }catch (NacosException e) {

e.printStackTrace();

        }

}

private void clearRoute() {

for(String id :ROUTE_LIST) {

this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();

        }

ROUTE_LIST.clear();

    }

private void addRoute(RouteDefinition definition) {

try {

routeDefinitionWriter.save(Mono.just(definition)).subscribe();

            ROUTE_LIST.add(definition.getId());

        }catch (Exception e) {

e.printStackTrace();

        }

}

private void publish() {

this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this.routeDefinitionWriter));

    }

@Override

    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {

this.applicationEventPublisher = applicationEventPublisher;

    }

}

这一步一定要在nacos添加配置之前,因为配置类添加的监听如果nacos上的配置没有进行添加或者修改,网关是读不到配置的,因为他监听的是改变。

里面的name参数,gateway已经规定好了,不允许随意修改,值如下图所示。

本方式不需要建配置类,原理就是通过配置中心直接把动态路由的配置读到配置文件中,首先新建properties文件,

server.port=9547

spring.application.name=cloud-alibaba-gatewayaa

spring.cloud.nacos.discovery.server-addr=localhost:8848

spring.cloud.nacos.config.server-addr=localhost:8848

spring.cloud.nacos.config.file-extension=properties

spring.cloud.nacos.config.group=DEFAULT_GROUP

spring.cloud.gateway.discovery.locator.enabled=true

进入nacos,新建配置

yml配置如下所示
相似回答