spring cloud alibaba 之动态网关Getway【Nacos】

2020-12-08 10:39
12699
0

基于上一篇 Getway继续讲的,如果不了解请您先了解上一篇  点击进入

基于Nacos作为配置中心首先要修改的就是配置文件

这里使用bootstrap.yml。作为服务的配置文件

为什么使用bootstrap.yml,因为application.yml在bootstrap.yml之后加载。在加载网关的时候我们要在application加载之前做一些配置等操作。

具体配置如下

server:
  port: 9001
spring:
  application:
    name: yyhoucGetway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      username: nacos
      password: nacos
      config:
        server-addr: 127.0.0.1:8848
logging:
  pattern:
  path: E:/log/spring.log
  level:
    root:  info

有了配置后,我们需要做一些操作去刷新路由节点。

首先我们要读取Nacos地址与热加载

所以我们要定义

Naocs地址与namespace

我们要根据要对其进行随着服务启动而启动

这里是用来了启动的注解@PostConstruct

去Nacos 拿去配置,就需要使用NacosFactory.createConfigService来创建配置服务

这个工厂创建是一个重载的方法,

1.可以直接使用地址字符串

2.可以传入一个properties对象。

为了后期可扩展性,这里使用了properties。

@Value("${spring.cloud.nacos.config.server-addr}")
private String serverAddr;
@Value("${spring.cloud.nacos.config.namespace:-1}")
private String namespace;
@PostConstruct
public void init() {

    Properties properties = new Properties();
    properties.put("serverAddr", serverAddr);
    if(!"-1".equals(namespace)){
        properties.put("namespace", namespace);
    }
    //从工厂方法获取ConfigService
    ConfigService configService = NacosFactory.createConfigService(properties);


}

然后要进行的就是配置文件的获取与加载

String configInfo = configService.getConfig(dataId, group,5000);
List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
for(RouteDefinition definition : definitionList){
    nacosRouteService.addRoute(definition);
}

nacosRouteService.java

package com.yyhouc.getway.config;

import org.springframework.beans.factory.annotation.Autowired;
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 java.util.ArrayList;
import java.util.List;

/**
 * 动态路由服务
 */
@Service
public class NacosRouteService implements ApplicationEventPublisherAware {

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    private ApplicationEventPublisher applicationEventPublisher;

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

    public  void clearRoute() {
        for(String id : ROUTE_LIST) {
            this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
        }
        ROUTE_LIST.clear();
    }

    public void addRoute(RouteDefinition definition) {
        try {
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            ROUTE_LIST.add(definition.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void publish() {
        this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this.routeDefinitionWriter));
    }

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

做好了初始化加载我们就要去做热加载,这里Nacos 提供了监听的Listener

public void routeByNacosListener() {
    try {
        Properties properties = new Properties();
        properties.put("serverAddr", serverAddr);
        if(!"-1".equals(namespace)){
            properties.put("namespace", namespace);
        }
        //从工厂方法获取ConfigService
        ConfigService configService = NacosFactory.createConfigService(properties);
        configService.addListener(dataId, group, new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                nacosRouteService.clearRoute();
                try {
                    List<RouteDefinition> gatewayRouteDefinitions = JSONObject.parseArray(configInfo, RouteDefinition.class);
                    for (RouteDefinition routeDefinition : gatewayRouteDefinitions) {
                        nacosRouteService.addRoute(routeDefinition);
                    }
                    nacosRouteService.publish();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

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

 

全部评论