spring cloud 2020 接入 nacos 2 脚手架

Posted anxpp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring cloud 2020 接入 nacos 2 脚手架相关的知识,希望对你有一定的参考价值。

tops

前言

这其实没啥好写的,不过最新版本有些坑,再加上国内的文档真的是一言难尽,就记录一下吧。

nacos 官方文档:https://nacos.io/zh-cn/docs/quick-start.html
spring cloud 官方文档:https://spring.io/projects/spring-cloud

该demo同时整合了 spring cloud sleuth 分布式链路追踪,文内不再细讲

Nacos

nacos 是集服务发现和配置中心一体的组件,自带后台并集成用户权限,支持动态配置。

nacos 安装比较简单,下载后直接解压就有windows和linux的脚本可用,在这之前请确保安装好 mavenjava
nacos并不支持较新的 java 版本,建议使用 java 8 或者 11 。

下载好后直接解压,windows下使用cmd脚本启动,mac或者linux使用sh脚本启动,便于测试,可直接使用单机模式启动:

./startup.sh -m standalone

集群方式参考官方文档即可。

启动后可访问 http://127.0.0.1:8848/nacos 浏览控制台。

分布式服务

这里创建 2 个服务: api(消费者) 和 content (生产者),Idea 中使用 spring initializr 创建即可。

创建后添加相关的依赖,相关版本如下:

    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
    </properties>

注意: 当前最新版本的 nacos client 已不再支持 spring-cloud-starter-netflix-ribbon ,这是官方文档没提到过的,相反,文档上是写着支持 robbin 的,所以调试了很久,直到后面找个了相关的 issue ,所以我们直接使用 openfeign

Servive Content(生产者)

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>nacosServiceContent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacosServiceContent</name>
    <description>nacosServiceContent</description>
    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
        <nacos-client.version>1.4.1</nacos-client.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>$spring-cloud.version</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>$spring-cloud-alibaba.version</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class NacosServiceContentApplication 

    public static void main(String[] args) 
        SpringApplication.run(NacosServiceContentApplication.class, args);
    

@EnableDiscoveryClient 开启服务发现功能

配置文件

bootstrap.yml

server:
  port: 9091

spring:
  application:
    name: service-content
  cloud:
    nacos:
      config:
        file-extension: yaml
        server-addr: 127.0.0.1:8848
        extension-configs:
          - data-id: content-develop.properties
            refresh: true
      discovery:
        server-addr: 127.0.0.1:8848
        service: service-content

application.yml

spring:
  profiles:
    active: dev

较新版的 spring cloud 不再自动读取 bootstrap.yml ,需要引入 spring-cloud-starter-bootstrap

nacos 配置文件ID结构为三段式:$prefix-$spring.profiles.active.$file-extension

  • prefix 默认为 spring.application.name,可使用 spring.cloud.nacos.config.prefix 自定义
  • spring.profiles.active 如果为空,则配置文件ID两段式
  • file-extension 默认为 properties,目前还支持yaml

其中 extension-configs 数组可配置额外的配置文件,可参考文档

controller

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController 

    @Value("$useLocalCache:initValue")
    private String useLocalCache;

    private static final Logger log = LoggerFactory.getLogger(ConfigController.class);

    @RequestMapping("/get")
    public String get() 
        log.info("test content");
        return String.format("%s", useLocalCache);
    

@RefreshScope 开启配置自动刷新
@Value("$useLocalCache:initValue") 注入配置,可指定默认值

Servive Api(消费者)

pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>nacosServiceApi</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacosServiceApi</name>
    <description>nacosServiceApi</description>
    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

        <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>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-ribbon -->
<!--        <dependency>-->
<!--            <groupId>org.springframework.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>-->
<!--            <version>2.1.6.RELEASE</version>-->
<!--        </dependency>-->

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>$spring-cloud.version</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>$spring-cloud-alibaba.version</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class NacosServiceApiApplication 

//    @LoadBalanced
//    @Bean
//    public RestTemplate restTemplate() 
//        return new RestTemplate();
//    

    public static void main(String[] args) 
        SpringApplication.run(NacosServiceApiApplication.class, args);
    


@RefreshScope 开启配置自动刷新
@EnableFeignClients 开启 feign 客户端

// 注释掉的部分(pom同)为测试 robbin 的,实际不可用

配置文件

bootstrap.yml

server:
  port: 9090

spring:
  application:
    name: service-api
  cloud:
    nacos:
      config:
        file-extension: yaml
        server-addr: 127.0.0.1:8848
        extension-configs:
          - data-id: content-develop.properties
            refresh: true
      discovery:
        server-addr: 127.0.0.1:8848
        service: service-api

application.yml

spring:
  profiles:
    active: dev

配置大致同 content 服务的配置

controller

import com.example.nacosserviceapi.client.ContentClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/echo")
@RefreshScope
public class ConfigController 

//    @Value("$service-url.content")
//    private String urlContent;

//    private final RestTemplate restTemplate;

    @Autowired
    private ContentClient contentClient;
//
//    @Autowired
//    public ConfigController(RestTemplate restTemplate) 
//        this.restTemplate = restTemplate;
//    

    private static final Logger log = LoggerFactory.getLogger(ConfigController.class);

    @RequestMapping(value = "/test/str", method = RequestMethod.GET)
    public String echo(@PathVariable String str) 
//        String url = urlContent + "/config/get";
//        System.out.println("urlContent: " + url);
//        return restTemplate.getForObject(url, String.class) + str;
        log.info("tapi est");
        return contentClient.config();
    


client

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient("service-content")
public interface ContentClient 

    @RequestMapping("/config/get")
    String config();

@FeignClient("service-content") 指定要调用的服务

动态配置与服务发现测试

这里通过 api 调用 content 并返回 content 读取的配置文件数据完成配置服务、注册服务和服务调用的测试。

首先通过 nacos 控制台添加配置项:

dataId: service-content-dev.yaml
groupId: DEFAULT_GROUP
配置格式: yaml
配置内容L: useLocalCache: testConfig

启动服务:
api 端口为 9090
content 端口为 9091

这时候能在 nacos 控制台看到服务注册成功,发起调用测试:

http://127.0.0.1:9090/echo/test/123

如果正常,会返回刚刚添加的配置 testConfig,可以尝试修改 useLocalCache 的值,再调用该接口。

细心的朋友会发现输出的日志格式为:

2021-11-16 11:47:06.182  INFO [service-content,e968ce128347c604,baf888e4e7f7ec89]......

这里面 service-content,e968ce128347c604,baf888e4e7f7ec89 为分布式链路追踪支持,两端id分别为tranceId和spanId,具体可参考文档

Spring Cloud Gateway

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>nacosServiceGateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacosServiceGateway</name>
    <description>nacosServiceGateway</description>
    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>2020.0.4</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-spring-boot2 -->
        <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring-boot2</artifactId>
        </dependency>

        <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>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>$spring-cloud.version</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>$spring-cloud-alibaba.version</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

启动类

import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.timelimiter.TimeLimiterConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory;
import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JConfigBuilder;
import org.springframework.cloud.client.circuitbreaker.Customizer;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.time.Duration;

@SpringBootApplication
@EnableDiscoveryClient
public class NacosServiceGatewayApplication 

    public static void main(String[] args) 
        SpringApplication.run(NacosServiceGatewayApplication.class, args);
    

    // 优先级低于配置文件
    @Bean
    public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() 
        return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
                .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build())
                .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
                .build());
    

    @Bean
    public GlobalFilter customFilter() 
        return new CustomGlobalFilter();
    

    public static class CustomGlobalFilter implements GlobalFilter, Ordered 

        private static final Logger log = LoggerFactory.getLogger(CustomGlobalFilter.class);

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) 
            log.info("custom global filter");
            return chain.filter(exchange);
        

        @Override
        public int getOrder() 
            return -1;
        
    


defaultCustomizer 是集成 Resilience4J 轻量级容错组件
customFilter 为自定义全局过滤器,这里主要用来测试分布式服务追踪。

配置文件

bootstrap.yml

server:
  port: 9080

spring:
  application:
    name: service-gateway
  cloud:
    nacos:
      config:
        file-extension: yaml
        server-addr: 127.0.0.1:8848
        extension-configs:
          - data-id: gateway-develop.yaml
            refresh: true
      discovery:
        server-addr: 127.0.0.1:8848
        service: service-gateway

application.yml

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: service-content
          uri: lb://service-content
          predicates:
            - Path=/content/**
          filters:
            - StripPrefix=1
        - id: service-api
          uri: lb://service-api
          predicates:
            - Path=/api/**
          filters:
            - StripPrefix=1

#resilience4j.circuitbreaker:
#  instances:
#    backendA:
#      registerHealthIndicator: true
#      slidingWindowSize: 100
#    backendB:
#      registerHealthIndicator: true
#      slidingWindowSize: 10
#      permittedNumberOfCallsInHalfOpenState: 3
#      slidingWindowType: TIME_BASED
#      recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate
#
#resilience4j.timelimiter:
#  instances:
#    backendA:
#      timeoutDuration: 2s
#      cancelRunningFuture: true
#    backendB:
#      timeoutDuration: 1s
#      cancelRunningFuture: false

调用测试

http://127.0.0.1:9080/api/echo/test/123

输出跟 http://127.0.0.1:9090/echo/test/123 是一致的。

参考文档

Nacos:https://nacos.io/zh-cn/docs/what-is-nacos.html
Resilience4J:https://github.com/resilience4j/resilience4j
Nacos Config:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
Nacos discovery:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery
Spring Cloud Gateway:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/
Spring Cloud OpenFeign:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/
Spring Cloud Sleuth:https://docs.spring.io/spring-cloud-sleuth/docs/3.1.0-SNAPSHOT/reference/htmlsingle/

以上是关于spring cloud 2020 接入 nacos 2 脚手架的主要内容,如果未能解决你的问题,请参考以下文章

spring cloud 2020 接入 nacos 2 脚手架

spring cloud 2020 接入 nacos 2 脚手架

spring cloud Nacos Config配置中心

Spring Cloud Alibaba - 17 Nacos Config 配置中心 应用篇

Spring Cloud Alibaba - 03 注册中心Nacos 应用篇(上)

spring cloud的坑