Nacos Gateway动态路由实战

*说明:本次测试使用的gateway是2.2.2.RELEASE版本,其他版本可能存在不同

一、引入本次测试需要的pom依赖
<!--gateway网关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--nacos依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--json工具包-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
二、配置文件设置(*配置文件不生效的把名字改为bootstrap.yml)
server:
  port: 8200

spring:
  application:
    name: lc-gateway

  cloud:
    nacos:
      discovery:
        #注册中心地址
        server-addr: 106.12.146.239:8848
      config:
        server-addr: 106.12.146.239:8848
        # 配置中心-指定命名空间
        namespace: bb79a8c4-e4e1-4a27-bceb-0810f278b5aa
        # 指定配置文件后缀
        file-extension: yaml
        #配置组
        group: DEFAULT_GROUP
        #配置dateId
        data-id: lc-gateway
        #获取配置超时时间
        timeout: 5000

    gateway:
      #设置超时时间默认
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s

ps:这里集成了nacos配置中心想了解详情请移步Spring Cloud如何集成Nacos配置中心

三、动态路由实现
package com.lc.api.gateway.config;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.stereotype.Service;
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;

/**
 * 动态路由,可以通过获取Bean才做该类,提供增删改查已经发布功能
 *
 * @Author: lc
 * @Date: 2020/7/8 15:49
 */
@Service
public class DynamicRouteConfig implements ApplicationEventPublisherAware {

    private static final Logger logger = LoggerFactory.getLogger(DynamicRouteConfig.class);

    @Autowired
    private RouteDefinitionWriter routedefinitionWriter;

    private ApplicationEventPublisher publisher;

    @Value("${spring.cloud.nacos.config.data-id}")
    private String dataId;
    @Value("${spring.cloud.nacos.config.group}")
    private String group;
    @Value("${spring.cloud.nacos.config.server-addr}")
    private String serverAddr;
    @Value("${spring.cloud.nacos.config.namespace}")
    private String namespace;
    @Value("${spring.cloud.nacos.config.timeout}")
    private long timeout;

    private static final List<String> ROUTE_LIST = new ArrayList<>();

    @PostConstruct
    public void dynamicRouteByNacosListener() {
        try {
            Properties prop = new Properties();
            prop.put("serverAddr", serverAddr);
            prop.put("namespace", namespace);
            ConfigService config = NacosFactory.createConfigService(prop);
            String content = config.getConfig(dataId, group, timeout);
            publisher(content);
            config.addListener(dataId, group, new Listener() {
                @Override
                public void receiveConfigInfo(String config) {
                    publisher(config);
                }

                @Override
                public Executor getExecutor() {
                    return null;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 增加路由
     *
     * @param def
     * @return
     */
    public Boolean addRoute(RouteDefinition def) {
        try {
            routedefinitionWriter.save(Mono.just(def)).subscribe();
            ROUTE_LIST.add(def.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 删除路由
     *
     * @return
     */
    public Boolean clearRoute() {
        for (String id : ROUTE_LIST) {
            routedefinitionWriter.delete(Mono.just(id)).subscribe();
        }
        ROUTE_LIST.clear();
        return Boolean.FALSE;
    }

    /**
     * 发布路由
     */
    private void publisher(String config) {
        clearRoute();
        try {
            logger.info("Start updating dynamic routing ....");
            List<RouteDefinition> routeDefinitionList = JSONObject.parseArray(config, RouteDefinition.class);
            for (RouteDefinition route : routeDefinitionList) {
                logger.info(route.toString());
                addRoute(route);
            }
            publisher.publishEvent(new RefreshRoutesEvent(this.routedefinitionWriter));
            logger.info("update completed ");
        } catch (Exception e) {
            logger.error("Failed to update routing information", e);
            e.printStackTrace();
        }

    }

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

}
四、nacos配置中心设置

1.说明

237F19BA-9D48-6019-D1E8-9C32CB0D95AD.png

2.新建一个网关配置

817A8464-0886-8845-02CD-F83F644E6704.png

3. 添加配置格式如下

0AC4B6FB-1206-DE0C-2FD9-A7411B5AAC33.png

这里我就不注释了大家应该都能看懂

[
    {
        "filters": [
            {
                "args": {
                    "parts": "1"
                },
                "name": "StripPrefix"
            }
        ],
        "id": "authent1",
        "order": -1,
        "predicates": [
            {
                "args": {
                    "pattern": "/authent/**"
                },
                "name": "Path"
            }
        ],
        "uri": "lb://lc-authenticate"
    }
]
 五、测试

3EC38257-1026-94EA-60B3-A9276F357F9F.png

收藏 (0)
评论列表
正在载入评论列表...
我是有底线的
为您推荐
    暂时没有数据