nacos 教程


nacos 教程

1. 简介

1.1 介绍

Nacos 是阿里巴巴推出来的一个新开源项目,这是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

1.2 安装

下载

https://github.com/alibaba/nacos/tags

在这里选择版本 1.2.1 为稳定版本,1.3 为测试版本。然后选择下载 linux 选择下载 gz, windows 下载 zip 格式的。大约50MB

https://github.com/alibaba/nacos/releases/tag/1.2.1

这个是版本介绍

https://github.com/alibaba/nacos/releases

linux版本

tar -zxvf 文件名

然后 进入bin 目录

sh startup.sh -m standalone

windows版本

点击 bin 目录下的startup.cmd 就可以了。

访问:

localhost:8848/nacos

输入默认账号密码:nacos,nacos

测试是否成功

curl -X POST "127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"

返回true,就说明配置成功

刷新页面

****

1.3 配置mysql

  • 创建新的nacos_config database

    此处的mysql 是我用docker 创建的

    docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
    
  • 复制nacos 安装路径下 config 文件夹下的nacos-mysql.sql,并且导入nacos_config 的数据库中

  • 配置NACOS_PATH/conf/application.properties

    spring.datasource.platform=mysql
     
    db.num=1
    db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    db.user=root
    db.password=root
    
  • 重启配置

    sh shutdown.sh
    sh startup.sh -m standalone
    

1.4 概念介绍

  • 配置

在系统开发过程中,开发者通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成。配置变更是调整系统运行时的行为的有效手段。

  • 配置管理

系统配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动。

  • 配置项

一个具体的可配置的参数与其值域,通常以 param-key=param-value 的形式存在。例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|ERROR) 就是一个配置项。

  • 配置集

一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。

  • 配置集 ID

Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。

  • 配置分组

Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。

  • 配置快照

Nacos 的客户端 SDK 会在本地生成配置的快照。当客户端无法连接到 Nacos Server 时,可以使用配置快照显示系统的整体容灾能力。配置快照类似于 Git 中的本地 commit,也类似于缓存,会在适当的时机更新,但是并没有缓存过期(expiration)的概念。

2. 讲解

2.1 入门流程

发布配置

添加依赖

版本的话,和nacos 页面版本,尽量一致。现在版本在2.0

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>kaoyan-cloud</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client -->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.4.0</version>
        </dependency>

    </dependencies>

</project>

main 函数

package com.ak;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;

import java.util.Properties;

public class demo1 {

    public static void main(String[] args) throws NacosException {
        // 使用nacos 来获取配置
        String serverAddr="47.100.104.187:8848";

        String dataID="nacos-simple-demo1.yml";

        String group="DEFAULT_GROUP";


        Properties properties =new Properties();
        properties.put("serverAddr",serverAddr);
        ConfigService service=NacosFactory.createConfigService(properties);

        String config=service.getConfig(dataID,group,5000);
        System.out.println(config);
    }
}

远程获取结果

2.2 配置管理

1) 命名空间

新建命名空间

在不同的命名空间下,建立不同的yml

image-20210113093126400

然后开始运行

package com.ak;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;

import java.util.Properties;

public class demo2 {

    public static void main(String[] args) throws NacosException {
        // 使用nacos 来获取配置
        String serverAddr="47.100.104.187:8848";

        String dataID="nacos-simple-demo1.yml";

        String group="DEFAULT_GROUP";
        String nameSpace="cf6270d3-a5d2-46ac-a36a-051ef8fd0151";


        Properties properties =new Properties();
        properties.put("serverAddr",serverAddr);
        properties.put("namespace",nameSpace);
        ConfigService service=NacosFactory.createConfigService(properties);

        String config=service.getConfig(dataID,group,5000);
        System.out.println(config);
    }
}

结果

image-20210113093211004

2) 监听

package com.ak;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;

import java.util.Properties;
import java.util.concurrent.Executor;

public class demo2 {

    public static void main(String[] args) throws NacosException {
        // 使用nacos 来获取配置
        String serverAddr="47.100.104.187:8848";

        String dataID="nacos-simple-demo1.yml";

        String group="DEFAULT_GROUP";
        String nameSpace="cf6270d3-a5d2-46ac-a36a-051ef8fd0151";
        Properties properties =new Properties();
        properties.put("serverAddr",serverAddr);
        properties.put("namespace",nameSpace);
        ConfigService service=NacosFactory.createConfigService(properties);
        String config=service.getConfig(dataID,group,5000);
        System.out.println(config);
        // 添加了监听,当配置信息内容发生改变了,就会发生改变
        service.addListener(dataID, group, new Listener() {
            @Override
            public Executor getExecutor() {
                return null;
            }

            @Override
            public void receiveConfigInfo(String s) {
                System.out.println(s);
            }
        });
        while (true){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

结果

image-20210113094321484

3) 登录管理

生成code

package com.ak;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 *使用验证码
 */
public class demo3 {
    public static void main(String[] args) {
        String password=new BCryptPasswordEncoder().encode("123");
        System.out.println(password);
    }
}

image-20210113095655070

修改数据库user 和admin

use nacos_config;
insert into users(username,password,enabled) values("joker","$2a$10$7hViVnEt5Z8k6KfvTcZvR.kSQvNKuTaH/3H.9EKlQLZ7IIlFJw5Ia",TRUE);
insert into roles(username,role) values("joker","ROLE_ADMIN");

退出,使用joker,密码123 登录

image-20210113095744715

3. 整合SpringCloud(配置中心+服务发现)

3.1 写配置

image-20210113104707209

image-20210113134337305

3.2 创建父工程demo

记住springboot 版本需要在2.0到2.3 之间,以上的话。nacos 是不支持的

2.2.12 版本是nacos 所支持的最高版本

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.2.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <modules>
        <module>nacos-provider</module>
        <module>nacos-consumer</module>
    </modules>
    <properties>
        <java.version>11</java.version>
        <nacos-config>2.2.3.RELEASE</nacos-config>
        <nacos-discovery>2.2.3.RELEASE</nacos-discovery>

    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR9</version>
                <type>pom</type>
                <scope>runtime</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                <version>${nacos-discovery}</version>
            </dependency>

            <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-config -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
                <version>${nacos-config}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.3 创建nacos-provider 子工程

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>
       <artifactId>demo</artifactId>
        <groupId>com.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>nacos-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacos-provider</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

创建bootstrap.yml

bootstrap.yml 优先级是高于application.yml,效果是一样的

如果你的 nacos 在本地的话,application.yml 是没有问题的

如果是在网上的话,需要使用bootstrap.yml ,

不然其中的server-addr 是没有效果的

server:
  port: 8070
spring:
  application:
    name: nacos-provider
  cloud:
    # nacos服务地址
    nacos:
      config:
        server-addr: 47.100.104.187:8848
        namespace: cf6270d3-a5d2-46ac-a36a-051ef8fd0151
        group: DEFAULT_GROUP
        file-extension: yaml
        prefix: nacos-provider
      discovery:
        server-addr: 47.100.104.187:8848
        namespace: cf6270d3-a5d2-46ac-a36a-051ef8fd0151

创建主程序

@EnableDiscoveryClient开启服务发现

package com.example.nacosprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
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;

@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderApplication {

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

}

创建controller

package com.example.nacosprovider.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import java.time.LocalTime;

@RefreshScope
@RestController
public class ProviderController {
    @Value("${provider.name}")
    private String devConfig;

    /**
     * 这个是用来测试配置是否正确的方法
     * @return
     */
    @GetMapping("invoke")
    public String invoke() {
        return LocalTime.now() + " invoke,name:" + devConfig;
    }

    /**
     * 这个是用来服务发现的服务方法
     * @param string
     * @return
     */
    @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
    public String echo(@PathVariable String string) {
        return "8070 端口--提供服务的方法 " + string;
    }
}

3.4 创建nacos-consumer 子工程

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>
        <artifactId>demo</artifactId>
        <groupId>com.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>nacos-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacos-consumer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

创建bootstrap.yml

server:
  port: 8071
spring:
  application:
    name: nacos-consumer
  cloud:
    # nacos服务地址
    nacos:
      server-addr: 47.100.104.187:8848
      config:
        namespace: cf6270d3-a5d2-46ac-a36a-051ef8fd0151
        group: DEFAULT_GROUP
        file-extension: yaml
        server-addr: 47.100.104.187:8848
      discovery:
        server-addr: 47.100.104.187:8848
        namespace: cf6270d3-a5d2-46ac-a36a-051ef8fd0151

创建主程序

package com.example.nacosconsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
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;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApplication {

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

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

    }

    /**
     * 这个是是用来测试 消费端能否连接服务端的
     */
    @RestController
    public class TestController {
        private final RestTemplate restTemplate;

        @Autowired
        public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}
        @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
        public String echo(@PathVariable String str) {
            return restTemplate.getForObject("http://nacos-provider/echo/" + str, String.class);
        }
    }
}

创建controller

package com.example.nacosconsumer.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalTime;

@RefreshScope
@RestController
public class ConsumerController {
    @Value("${consumer.name}")
    private String devConfig;

    /**
     * 这个是用来测试 消费端的接口是否正确
     * @return
     */
    @GetMapping("invoke")
    public String invoke() {
        return LocalTime.now() + " invoke,name:" + devConfig;
    }
}

3.5 测试

测试provider 配置信息是否成功

http://localhost:8070/invoke

image-20210113135356397

测试consumer 配置信息是否成功

http://localhost:8071/invoke

image-20210113135434343

查看consumer 能否调用 provider

http://localhost:8071/echo/22

image-20210113135524712

查看是否注册成功

image-20210113135606956

两个服务都成功

4. 配置讲解

4.1 dataid 配置讲解

在 Nacos Spring Cloud 中,dataId 的完整格式如下:

${prefix}-${spring.profiles.active}.${file-extension}
  • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
  • spring.profiles.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 propertiesyaml 类型。

4.2 实现自动装填

package cn.com.geostar.datasource;
 
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
 
/**
 * @author xiawei
 * @date 2020/8/10 11:33
 */
 
@Component
@RefreshScope
@ConfigurationProperties(prefix = "jedispool.config")
public class JedisPoolConfigure {
    private boolean enable;
    private String host;
    private Integer port;
    private String password;
    private Integer timeOut;
    private Integer maxIdle;
    private Integer maxWaitMillis;
    private Integer maxTotal;
}
上次编辑于: 2021/10/12 下午4:55:55
贡献者: fakerlove1