SpringCloudAlibaba: Nacos service registration and discovery and configuration center

Nacos Service Registration and Discovery and Configuration Center

Speak ahead

Related code and note address of this chapter: Airline ticket🚀
🌍Github: 🚀Java Super God Road: [🍔Java Full Ecological Technology Study Notes, Let’s Super God Together 🍔]

🪐CSDN: 🚀Java Super God Road: [🍔Java Full Ecological Technology Study Notes, Let’s Super God together 🍔]

Download URL of the installation package required for this chapter

Link: https://pan.baidu.com/s/1ncltc-c4u5_jXAmaTOTJMA
Extraction code: ra0l

table of Contents

1. What is SpringCloud Alibaba?

1.1 SpringCloud Alibaba

Spring Cloud Alibaba is a sub-project under Spring Cloud. Spring Cloud Alibaba provides a one-stop solution for distributed application development. It contains all the components required to develop distributed applications, allowing you to easily use Spring Cloud Develop applications and use Spring Cloud Alibaba. You only need to add some annotations and a small amount of configuration to connect Spring Cloud applications to Alibaba's distributed solutions, and use Alibaba middleware to build a distributed application system;

Spring Cloud Alibaba is the integration of Alibaba's open source middleware and Spring Cloud system:

image-20210609153205389

Main features :

1. Flow control and service degradation : Use Alibaba Sentinel for flow control, disconnection and system adaptive protection;

2. Service registration and discovery : instances can be registered on Alibaba Nacos, customers can use Spring-managed beans to discover instances, and support Ribbon client load balancers through Spring Cloud Netflix;

3. Distributed configuration : use Alibaba Nacos as data storage;

4. Event-driven : build highly scalable event-driven microservices connected to Spring Cloud Stream RocketMQ Binder;

5. Message bus : use Spring Cloud Bus RocketMQ to link the nodes of the distributed system;

6. Distributed transaction : Supports the high-performance and easy-to-use Seata distributed transaction solution;

7. Dubbo RPC : extend the communication protocol from Spring Cloud service to service call through Apache Dubbo RPC;

1.2 SpringCloud Alibaba version correspondence

The latest version: Spring Cloud Alibaba 2.2.1

image-20210609153413607

Spring Cloud Alibaba 2.1.0 RELEASE corresponds to Spring Cloud Greenwich version

Spring Cloud Alibaba 2.2.0 RELEASE corresponds to Spring Cloud Hoxton.RELEASE version

Spring Cloud Alibaba 2.2.1 RELEASE corresponds to Spring Cloud Hoxton.SR3 version

1.3 What is Nacos?

Nacos is an open source project launched by Alibaba in July 2018. It is a dynamic service registration and discovery, configuration management and service management platform that is easier to build cloud native applications; (Nacos: Nacos)

Nacos is committed to quickly realize dynamic service registration and discovery, service configuration, service metadata and traffic management;

Nacos is a component under Spring cloud alibaba;

Nacos is approximately equal to spring cloud eureka (registration center) + spring cloud config (configuration center)

Nacos official website: https://nacos.io/

Nacos features

  • Service discovery and health check
  • Dynamic configuration management
  • Dynamic DNS service
  • Service and metadata management (the degree of management platform, nacos also has a ui page, you can see the registered service and its instance information (metadata information), etc.), dynamic service weight adjustment, dynamic service offline gracefully, Can go

2. Nacos operating environment deployment

At the end of this chapter, there are binary cluster deployment and K8s cluster deployment tutorials

2.1 Download Nacos binary package

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

2.2 Deployment & startup

#解压下载下来的nacos最新的二进制压缩包;
cd /opt
tar -zxvf nacos-server-1.3.1.tar.gz
cd /opt/nacos/bin
#启动nacos server
./startup.sh -m standalone
#注:单机环境必须带-m standalone参数启动,否则无法启动,不带参数启动的是集群环境;
#查看启动日志:
cat /opt/nacos/logs/start.out
Nacos relies on the Java environment, so make sure that the server is installed with the Java environment to start successfully

2.3 Access test

http://192.168.159.100:8848/nacos
#默认用户名密码:nacos/nacos
image-20210609153612886

3. Nacos service registration and discovery and service invocation

image-20210609153648835

Similar to Dubbo, microservice development is that the controller calls the controller, the caller is the service consumer, and the callee is the service provider. The service consumer and the service provider are relative concepts. The service consumer can also be called by another service. The service consumer at this time is also a service provider;

In actual development, we will register all services to the nacos registration center, and nacos will maintain and manage all our services;

By adding a starter dependency: spring-cloud-starter-alibaba-nacos-discoveryit seamlessly integrates with Nacos through automatic configuration, annotations and the Spring Boot programming model to achieve service registration and discovery. After the Double Eleven test, Nacos can be used as a service registration for a large-scale distributed system in a production environment center;

3.1 Implementing service providers

image-20210609153728714

3.1.2 Provider Pom file

<?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标签只能单继承一个SpringBoot 但是我们还需要继承SpringCloud-alibaba 所以我们把这里注释 通过最下面的dependencyManagement继承 -->
    <!--<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
    </parent>-->

    <groupId>com.eayon</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>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.0.RELEASE</spring-boot.version><!--指定SpringBoot版本-->
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version><!--指定spring-cloud-alibaba版本-->
    </properties>

    <dependencies>
        <!--SpringCloud Alibaba-Nacos 服务注册发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


    <!-- 继承SpringBoot及SpringCloud-Alibaba依赖 -->
    <dependencyManagement>
        <dependencies>
            <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>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <!--Maven编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!--SpringBoot编译插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.1.3 Provider application.yaml core configuration file

server:
  port: 18082

spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        #Nacos服务部署地址 ,如果是Nacos集群 多个IP之间使用逗号分割:192.168.159.100:8848,192.168.159.101:8848,192.168.159.102:8848
        server-addr: 192.168.159.100:8848
      #Nacos服务账号密码
      username: nacos
      password: nacos

3.1.4 The provider opens the service registration and discovery function

Add @EnableDiscoveryClientannotations to the startup class to enable service registration and discovery

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

@SpringBootApplication
@EnableDiscoveryClient//开启服务注册与发现功能
public class NacosProviderApplication {

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

}

3.1.5 The provider writes a test interface

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName EchoController
 * @Description //TODO
 * @date 2021/5/12 16:26
 * @Version: 1.0
 */
@RestController
public class EchoController {

    @GetMapping(value = "/getData")
    public Object getData(){
        return "测试数据";
    }
}

3.1.6 Provider's overall directory structure

image-20210609153905323

3.1.7 Start provider registration to Nacos

Start the provider project, and then check whether the registration is successful on the Nacos management platform

image-20210609153926255

3.2 Realize service consumers and multi-mode service invocation

3.2.1 Consumer Pom File

<?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标签只能单继承一个SpringBoot 但是我们还需要继承SpringCloud-alibaba 所以我们把这里注释 通过最下面的dependencyManagement继承 -->
    <!--<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
    </parent>-->

    <groupId>com.eayon</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>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.0.RELEASE</spring-boot.version><!--指定SpringBoot版本-->
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version><!--指定spring-cloud-alibaba版本-->
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version><!--指定spring-cloud版本-->
    </properties>

    <dependencies>
        <!--SpringCloud Alibaba-Nacos 服务注册发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--Ribbon 客户端负载均衡调用 这里为了测试所以Ribbon和Feign都引用了  一般这俩你选择一个使用即可-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <!--openfeign 客户端负载均衡调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


    <!-- 继承SpringBoot及SpringCloud-Alibaba依赖 和 SpringCloud依赖 -->
    <dependencyManagement>
        <dependencies>
            <!--SpringCloud-Alibaba-->
            <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>
            <!--SpringBoot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--SpringCloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <!--Maven编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!--SpringBoot编译插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.2.2 Consumer application.yaml core configuration file

server:
  port: 18083

spring:
  application:
    name: nacos-consumer
  cloud:
    nacos:
      discovery:
        #Nacos服务部署地址 ,如果是Nacos集群 多个IP之间使用逗号分割:192.168.159.100:8848,192.168.159.101:8848,192.168.159.102:8848
        server-addr: 192.168.159.100:8848
      #Nacos服务账号密码
      username: nacos
      password: nacos

3.2.3 Consumers enable service registration and discovery functions / Feign load balancing calls

Add @EnableDiscoveryClientannotations to the startup class to enable service registration and discovery functions (required)

Join in on the startup class @EnableFeignClientsnotes open Feign (if you are not using Feign call, you do not open)

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.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@EnableDiscoveryClient//开启服务注册与发现
@EnableFeignClients //开启feign
@SpringBootApplication
public class NacosConsumerApplication {

    /**
     * 如果使用restTemplate调用的话需要在这去加载
     * 如果你并不需要使用RestTemplate去进行调用 则无需加载
     *
     * @return
     */
    @LoadBalanced//负载均衡的去调用
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

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

}

3.2.3 Consumer's LoadBalancerClient and RestTemplate connection and load balancing access method

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author zhengtai.li
 * @ClassName TestController
 * @Description //TODO
 * @Copyright 2021 © kuwo.cn
 * @date 2021/5/12 17:02
 * @Version: 1.0
 */
@RestController
public class TestController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;//负载均衡客户端

    @Autowired
    private RestTemplate restTemplate;//restTemplate方式调用


    /**
     * 使用LoadBalancerClient和RestTemplate结和的方式来负载均衡访问
     *
     * @return
     */
    @GetMapping(value = "/echo1")
    public Object echo1() {
        //通过负载均衡客户端loadBalancerClient选择一个服务:nacos-provider为提供者注册到Nacos的serviceid
        //loadBalancerClient会根据serviceid去Nacos根据loadBalancerClient自己的负载均衡策略进行选择一个服务进行返回
        //如果使用loadBalancerClient手动进行负载均衡调用的话需要将消费者的主启动类中restTemplate方法上的@LoadBalanced注解去除掉,否则调用失败
        ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider");
        //通过如上获取到的服务 我们可以获取到该服务的IP和端口
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();
        //拼接请求地址:通过提供这注册到Nacos的serviceid和端口进行调用
        String url = String.format("http://%s:%s/getData", host, port);
        System.out.println("请求地址为:" + url);
        //使用restTemplate进行调用
        String result = restTemplate.getForObject(url, String.class);
        return result;
    }
}

Note :

To use this method to call, you need @LoadBalancedto remove the annotations on the restTemplate method in the consumer's main startup class , otherwise the call will fail

image-20210609154140626

3.2.4 Consumer RestTemplate load balancing access method

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author zhengtai.li
 * @ClassName TestController
 * @Description //TODO
 * @Copyright 2021 © kuwo.cn
 * @date 2021/5/12 17:02
 * @Version: 1.0
 */
@RestController
public class TestController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;//负载均衡客户端

    @Autowired
    private RestTemplate restTemplate;//restTemplate方式调用


    /**
     * 使用RestTemplate结和的方式来负载均衡访问
     *
     * @return
     */
    @GetMapping(value = "/echo2")
    public Object echo2() {
        //如果使用restTemplate自动进行负载均衡调用的话需要在消费者主启动类中restTemplate方法上加上@LoadBalanced注解,否则调用失败
        //restTemplate会通过注册到Nacos的serviceid自动进行负载均衡选择一个服务调用
        String result = restTemplate.getForObject("http://nacos-provider/getData", String.class);
        return result;
    }

}

Note :

To use this method to call, you need to add @ LoadBalancedannotation to the restTemplate method in the consumer's main startup class , otherwise the call will fail

image-20210609154254895

3.2.5 Feign access methods of consumers (commonly used)

Define the service that needs to call the provider on the consumer side

image-20210609154330279

The methods in the service need to be consistent with those in the provider

Then, as shown in the figure, you also need to create the service degradation processing class and Feign configuration class corresponding to the Service.

如果你的某个Service不需要服务降级处理,在这里可以不需要配置fallback选项

如果你一个服务降级处理类都没有,那么这里也可以不需要配置configuration选项,因为该选项的Feign配置类就是用来加载服务降级处理类的

Define the service degradation processing class that calls Service on the consumer side

如果你的某个Service不需要服务降级处理,在这里可以不需要创建服务降级处理类

image-20210609154424825

Define Feign configuration classes on the consumer side

如果你一个服务降级处理类都没有,那么该Feign配置类也可以不需要创建

image-20210609154443763

Call test on the consumer side

import com.eayon.service.EchoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhengtai.li
 * @ClassName TestController
 * @Description //TODO
 * @Copyright 2021 © kuwo.cn
 * @date 2021/5/12 17:02
 * @Version: 1.0
 */
@RestController
public class TestController {

    @Autowired
    private EchoService echoService;//feign的声明式调用


    /**
     * 使用Feign进行调用
     *
     * @return
     */
    @GetMapping(value = "/echo3")
    public String echo3() {
        String data = echoService.echo();
        return data;
    }
}

3.3 Nacos client information caching

When Nacos goes down, can consumers still call the provider successfully?

When the consumer calls a provider's service and Nacos goes down, the consumer can still call the provider. Because consumers first go to the local cache to query the provider's invocation information, if the query is not available, they will go to Nacos to pull the provider information.

However, the provider has already been called before Nacos goes down, which also means that the consumer already has the provider's calling information locally, so Nacos is no longer dependent on it.

Later, we will analyze the source code of SpringCloud Alibaba in detail. In fact, it is stored in a Map and then cached in memory.

4. Nacos Config Configuration Center

Nacos provides use 存储配置and 其他元数据functions to provide server-side and client-side support for external configuration in distributed systems. Using Spring Cloud Alibaba Nacos Config, you can centrally manage the configuration of external properties of Spring Cloud applications in Nacos Server;

Spring Cloud Alibaba Nacos Config loads the configuration into the Spring environment during the bootstrap phase of startup;

Spring Cloud Alibaba Nacos Config uses DataId and GROUP to determine a configuration;

Similar products : Apollo, SpringCloud Config...

4.1 Read the configuration of the external Nacos Config configuration center

4.1.1 Create a pom file for the test service

The test service created here: nacos-config is only a service we use to test and read the Nacos config of the external configuration center, not the Nacos Config configuration center itself.

<?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标签只能单继承一个SpringBoot 但是我们还需要继承SpringCloud-alibaba 所以我们把这里注释 通过最下面的dependencyManagement继承 -->
    <!--<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/>
    </parent>-->

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

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.0.RELEASE</spring-boot.version><!--指定SpringBoot版本-->
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version><!--指定spring-cloud-alibaba版本-->
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version><!--指定spring-cloud版本-->
    </properties>

    <dependencies>
        <!-- Nacos服务注册发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--Nacos Config配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

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


    <!-- 继承SpringBoot及SpringCloud-Alibaba依赖 和 SpringCloud依赖 -->
    <dependencyManagement>
        <dependencies>
            <!--SpringCloud-Alibaba-->
            <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>
            <!--SpringBoot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--SpringCloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <!--Maven编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!--SpringBoot编译插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4.1.2 Create bootstrap.properties configuration file

image-20210609154641111

Why create bootstrap.properties?

Because the service must be connected to Nacos first when the service is started, if the configuration of connecting to Nacos is loaded in application.properties at the same time as some custom business configurations, then the priority of the business configuration and Nacos connection configuration cannot be controlled, so Nacos connection configuration is placed in bootstrap.properties.

bootstrap.properties在SpringBoot项目启动时优先于application.properties加载。

#端口
server.port=18084

#服务名称
spring.application.name=nacos-config

#nacos的用户名和密码
spring.cloud.nacos.username=nacos
spring.cloud.nacos.password=nacos

#Nacos注册发现连接地址,如果是集群模式有多个的话就用逗号隔开
spring.cloud.nacos.discovery.server-addr=192.168.159.100:8848

#nacos配置中心的连接地址,如果是集群模式有多个的话就用逗号隔开
spring.cloud.nacos.config.server-addr=192.168.159.100:8848

Note :

When you use the domain name to access Nacos,

The spring.cloud.nacos.config.server-addr configuration method is 域名:port, for example, the domain name of Nacos is nacos.power.com, and the listening port is 80.

Then spring.cloud.nacos.config.server-addr=nacos.power.com:80, note that port 80 cannot be omitted ;

4.2.3 Add registration discovery annotation to startup class

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

@EnableDiscoveryClient//服务注册于发现
@SpringBootApplication
public class NacosConfigApplication {

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

}

4.2.4 Add configuration in Nacos

image-20210609154758203
image-20210609154809279

DataId defaults to use the spring.application.nameconfiguration combined with the file extension (the configuration format uses .properties by default), and the GROUP does not configure the default use DEFAULT_GROUP;

4.2.5 Write test class to read external configuration

image-20210609154856697

4.2 Configuration method based on DataId as yaml extension

Nacos Config not only supports the .properties format by default, but also supports the yaml format. At this time, you only need to complete the following two steps:

1. Declare the DataId file extension in the bootstrap.properties configuration file of the application; the bootstrap.properties file configuration is as follows:

spring.cloud.nacos.config.file-extension=yaml
image-20210609154934606

2. Add a configuration with DataId as the yaml extension in the web console of Nacos, as shown below:

Data ID:       nacos-config2
Group  :       DEFAULT_GROUP
配置格式:        YAML
配置内容:        user.name: 张三丰
                user.age: 35
image-20210609155002654

3. Modify the service name of the application to be consistent with the newly configured DataId in Nacos

image-20210609155021760

4. Test whether the data read is newly configured

image-20210609155037434

4.3 Multi-environment configuration based on profile granularity

spring-cloud-starter-alibaba-nacos-configIn the load configuration when loaded with dataid not only for the ${spring.application.name}.${file-extension:properties}base configuration is also loaded dataid for the ${spring.application.name}-${profile}.${file-extension:properties}base configuration;

If you encounter in daily development of different configurations of multiple sets of environment, provided by Spring ${spring.profiles.active}to activate the configuration items using a configuration file;

4.3.1 Activate multiple environments

#激活多种环境 :dev、pro、test
# 比如这里配置dev,那么他会去Nacos Config中查询DataId=${spring.application.name} + "-" + ${spring.profiles.active}的配置  nacos-config2-dev.yaml
spring.profiles.active=dev

4.3.2 Configure the configuration in Nacos

image-20210609155256595
If multi-environment is activated and it is in YAML format, then the .yaml suffix must be added after the DataId, otherwise the configuration cannot be loaded

4.3.3 Test

image-20210609155312137

4.4 namespace and group in Nacos

Both the registration and discovery of the service or the configuration file have the isolation of namespace and group

In the above use, we did not specifically configure the namespace and group, because it is the default configuration.

默认namespace:public

默认group:DEFAULT_GROUP

Then we can divide the configuration into namespaces and groups for management

4.4.1 Create namespace

命名空间是公用的,创建了之后再服务列表和配置列表都会存在该命名空间

image-20210609155344838

4.4.2 Service registration discovery: create group and test

Create Group

#Nacos注册发现的命名空间配置  值为命名空间ID
spring.cloud.nacos.discovery.namespace=c7146cfc-a16d-4dd8-a005-ee680364d398
#Nacos注册发现的分组 如果该组不存在直接在此处进行定义即可
spring.cloud.nacos.discovery.group=DEV_GROUP
image-20210609155524498

View

image-20210609155542612

4.4.3 Configuration: create group and test

Just modify the group name directly, he will automatically create it

image-20210609155600309

Add the group and namespace configuration where the configuration file is located in the bootstrap.properties file of the application

#Nacos Config中配置文件所在的group
spring.cloud.nacos.config.group=DEV_GROUP
#Nacos Config中配置文件所在的namespace,值为命名空间ID
spring.cloud.nacos.config.namespace=c7146cfc-a16d-4dd8-a005-ee680364d398
image-20210609155627684

Start the application to test whether the configuration can be read

image-20210609155644759

V. Nacos replaces the data source

By default, Nacos uses the apache derby embedded database for data storage. In stand-alone mode, the nacos embedded database can be used for data storage, but the derby database is inconvenient to observe the basic situation of data storage. Since nacos 0.7 version, support for mysql has been added. Data source capability;

5.1 Install MySql database

http://www.zzvips.com/article/124798.html

5.2 Initialize the database

Initialize the MySQL database, the database initialization file:, nacos-mysql.sqlthe file can be obtained in the conf directory under the Nacos package

image-20210609155726866

Connect to the database

image-20210609155740973
image-20210609155801198

Execute SQL scripts to the database

image-20210609155821036
image-20210609155829212

5.3 Modify Nacos data source to MySql

Modify conf/application.propertiesfiles, adding support MySQL data source configuration, add (currently only supports mysql) url, user name and password for the data source;

#修改文件
vim /opt/nacos/conf/application.properties
image-20210609155912920

Delete junk files

rm -rf /opt/nacos/data /opt/nacos/logs /opt/nacos/bin/derby.log /opt/nacos/bin/logs /opt/nacos/bin/work

Restart Nacos

#关闭Nacos 然后等几秒再启动
/opt/nacos/bin/shutdown.sh
#单机启动Nacos的话一定要加-m standalone
/opt/nacos/bin/startup.sh -m standalone

Visit Nacos

We will find that the previous configuration is gone, because the database has been replaced

image-20210609160018288

Test database storage

Create a new configuration

image-20210609160043054

Check whether the database is successfully stored

image-20210609160109891

So far, it shows that the database replacement is successful

6. Nacos cluster deployment

6.1 Binary cluster deployment

6.1.1 Stop the original 100-node Nacos service

/opt/nacos/bin/shutdown.sh

6.1.2 Delete the junk files in the Nacos directory of 100 nodes

rm -rf /opt/nacos/data /opt/nacos/logs /opt/nacos/bin/derby.log /opt/nacos/bin/logs /opt/nacos/bin/work

6.1.3 Send the Nacos directory of 100 nodes to nodes 101 and 102

scp -r /opt/nacos/ [email protected]:/opt
scp -r /opt/nacos/ [email protected]:/opt

6.1.4 Configure the cluster.conf.example cluster file of 100, 101, and 102 Nacos nodes

#将cluster.conf.example文件名修改为cluster.conf
mv /opt/nacos/conf/cluster.conf.example /opt/nacos/conf/cluster.conf
#修改配置文件
vim /opt/nacos/conf/cluster.conf

The IP in the configuration files of the three nodes is the same, which is the IP of each node in the Nacos cluster

image-20210609160250301

6.1.5 The data sources of the three Nacos nodes must be the same MySql address and database

The Nacos database connection address of the 101 and 102 nodes needs to be changed from 127.0.0.1 to 192.168.159.100

image-20210609160328511

The production environment database needs to use the active/standby mode, so I won’t make a highly available database here.

6.1.6 Cluster startup

#三台节点挨个启动 启动命令相同
/opt/nacos/bin/startup.sh

#查看启动是否成功
jps

#查看启动日志
tail /opt/nacos/logs/nacos.log -f

6.1.7 Cluster environment test

Test whether the Nacos management platform of the three nodes is normal, and check whether the configuration is consistent, the consistency indicates that the connected MySql database is ok

image-20210609160413952

Modify the Nacos connection address of the service

image-20210609160428978

Test read configuration

image-20210609160444295

Nacos cluster node status has three roles: leader、follower、candidate;

When the leader goes down, a new leader will be voted from the remaining followers. The election algorithm is based on the Raft algorithm**;

After testing, it was found that there was a point that did not match the three roles. 3 nacos nodes were deployed, of which 2 were down and only one node was left. This node will become the candidate role, but at this time the nacos cluster can still register services and subscribe Service, (according to the correct theory, it should be: if there is no leader role in the nacos cluster, the node cannot register for the service, because the leader role handles transactional requests), which is more bizarre and needs to be studied

6.2 Nacos cluster unified entrance Nginx

6.2.1 Install the software package

#yum install epel-release -y
yum install nginx -y
yum  install keepalived -y

#彻底卸载nginx
yum  --purge autoremove nginx

6.2.2 Nginx configuration

cat > /etc/nginx/nginx.conf << "EOF"
worker_processes  1; 
 
events { 
    worker_connections  1024; 
} 
 
http { 
    include       mime.types; 
    default_type  application/octet-stream; 
 
    sendfile        on; 
 
    keepalive_timeout  65; 
 
    #nacos集群负载均衡 
    upstream nacos-cluster { 
        server 192.168.159.100:8848; 
        server 192.168.159.101:8848; 
        server 192.168.159.102:8848; 
    } 
 
    server { 
        listen       80; 
        server_name  localhost; 
 
        location / { 
            #root   html; 
            #index  index.html index.htm; 
            proxy_pass http://nacos-cluster; 
        } 
 
        error_page   500 502 503 504  /50x.html; 
        location = /50x.html { 
            root   html; 
        } 
    } 
 
} 
EOF

Start Nginx

systemctl daemon-reload
systemctl start nginx
systemctl enable nginx

#查看日志
tail /var/log/nginx/access.log -f

Finally, you only need to change all the places connected to the Nacos address in the project to the Nginx address, such as: 192.168.159.201:80 Finally, you must add 80

6.3 K8s deployment of Nacos cluster

Related blog: https://blog.csdn.net/fsjwin/article/details/110503029

6.3.1 Create Nacos database

Create a new database first:nacos-config

(You can name it whatever you want, but it needs to be the same as the database configuration item in the Nacos.yaml file)

Create Nacos configuration table

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info   */
/******************************************/
CREATE TABLE `config_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) DEFAULT NULL,
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  `c_desc` varchar(256) DEFAULT NULL,
  `c_use` varchar(64) DEFAULT NULL,
  `effect` varchar(64) DEFAULT NULL,
  `type` varchar(64) DEFAULT NULL,
  `c_schema` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_aggr   */
/******************************************/
CREATE TABLE `config_info_aggr` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) NOT NULL COMMENT 'group_id',
  `datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
  `content` longtext NOT NULL COMMENT '内容',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_beta   */
/******************************************/
CREATE TABLE `config_info_beta` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_tag   */
/******************************************/
CREATE TABLE `config_info_tag` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_tags_relation   */
/******************************************/
CREATE TABLE `config_tags_relation` (
  `id` bigint(20) NOT NULL COMMENT 'id',
  `tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
  `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `nid` bigint(20) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`nid`),
  UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = group_capacity   */
/******************************************/
CREATE TABLE `group_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = his_config_info   */
/******************************************/
CREATE TABLE `his_config_info` (
  `id` bigint(64) unsigned NOT NULL,
  `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `data_id` varchar(255) NOT NULL,
  `group_id` varchar(128) NOT NULL,
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL,
  `md5` varchar(32) DEFAULT NULL,
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `src_user` text,
  `src_ip` varchar(20) DEFAULT NULL,
  `op_type` char(10) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`nid`),
  KEY `idx_gmt_create` (`gmt_create`),
  KEY `idx_gmt_modified` (`gmt_modified`),
  KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = tenant_capacity   */
/******************************************/
CREATE TABLE `tenant_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';


CREATE TABLE `tenant_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `kp` varchar(128) NOT NULL COMMENT 'kp',
  `tenant_id` varchar(128) default '' COMMENT 'tenant_id',
  `tenant_name` varchar(128) default '' COMMENT 'tenant_name',
  `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
  `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
  `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
  `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';

CREATE TABLE `users` (
	`username` varchar(50) NOT NULL PRIMARY KEY,
	`password` varchar(500) NOT NULL,
	`enabled` boolean NOT NULL
);

CREATE TABLE `roles` (
	`username` varchar(50) NOT NULL,
	`role` varchar(50) NOT NULL,
	UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);

CREATE TABLE `permissions` (
    `role` varchar(50) NOT NULL,
    `resource` varchar(255) NOT NULL,
    `action` varchar(8) NOT NULL,
    UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);

INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);

INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

image-20210609160805683

6.3.2 部署

Nacos.yaml

如下nacos资源清单兼容最新2.0.1及以下所有版本

---
apiVersion: v1
kind: Service
metadata:
  name: nacos-headless
  labels:
    app: nacos-headless
spec:
  type: ClusterIP
  clusterIP: None
  ports:
    - port: 8848
      name: server
      targetPort: 8848
    - port: 9848
      name: client-rpc
      targetPort: 9848
    - port: 9849
      name: raft-rpc
      targetPort: 9849
      ## 兼容1.4.x版本的选举端口
    - port: 7848
      name: old-raft-rpc
      targetPort: 7848
  selector:
    app: nacos
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nacos-cm
  namespace: default
data:
  mysql.host: "10.0.74.21"
  mysql.db.name: "k8s-nacos"
  mysql.port: "25037"
  mysql.user: "editor_write"
  mysql.password: "[email protected]"
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nacos
  namespace: default
spec:
  serviceName: nacos-headless
  replicas: 3
  template:
    metadata:
      labels:
        app: nacos
      annotations:
        pod.alpha.kubernetes.io/initialized: "true"
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                      - nacos-headless
              topologyKey: "kubernetes.io/hostname"
      containers:
        - name: k8snacos
          imagePullPolicy: Always
          image: nacos/nacos-server:latest
          ports:
            - containerPort: 8848
              name: client
            - containerPort: 9848
              name: client-rpc
            - containerPort: 9849
              name: raft-rpc
            - containerPort: 7848
              name: old-raft-rpc
          env:
            - name: NACOS_REPLICAS
              value: "3"
            - name: MYSQL_SERVICE_HOST
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.host
            - name: MYSQL_SERVICE_DB_NAME
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.db.name
            - name: MYSQL_SERVICE_PORT
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.port
            - name: MYSQL_SERVICE_USER
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.user
            - name: MYSQL_SERVICE_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.password
            - name: MODE
              value: "cluster"
            - name: NACOS_SERVER_PORT
              value: "8848"
            - name: PREFER_HOST_MODE
              value: "hostname"
            - name: NACOS_SERVERS
              value: "nacos-0.nacos-headless.default.svc.cluster.local:8848 nacos-1.nacos-headless.default.svc.cluster.local:8848 nacos-2.nacos-headless.default.svc.cluster.local:8848"
  selector:
    matchLabels:
      app: nacos
---
# ------------------- App Service ------------------- #
#apiVersion: v1
#kind: Service
#metadata:
#  name: nacos-service
#  namespace: default
#  annotations:
#    nginx.ingress.kubernetes.io/affinity: "true"
#    nginx.ingress.kubernetes.io/session-cookie-name: backend
#    nginx.ingress.kubernetes.io/load-balancer-method: drr
#spec:
#  type: NodePort
#  ports:
#  - protocol: TCP
#    nodePort: 30003
#    port: 80
#    targetPort: 8848
#  selector:
#    app: nacos
#---
# ------------------- App Ingress ------------------- #
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nacos-web
  namespace: default
spec:        
  rules:
    - host: k8snacos.kwrd.mobi
      http:
        paths:
          - backend:
              service:
                name: nacos-headless
                port:
                  number: 8848
            path: /
            pathType: Prefix

参数说明

Service模块

image-20210609160853294

如图所示,对于nacos服务暴露了多个端口,由于我们部署的是最新的2.0.1版本,我这里还兼容了老版本的端口,对于新版本2.0.1,还需要暴露9848和9849 RPC端口。

数据库配置

image-20210609160913551

这里通过CinfigMap来为Nacos服务提供数据库连接配置。

StatefulSet

image-20210609160934945

如上框选信息分别为:Naocs负载数,Naocs容器端口,Nacos负载数环境变量(与前面对应)

image-20210609160954353

我们有三个Nacos负载,所以这里的NACOS_SERVERS的值也需要配置三个。

注意nacos-0.nacos-headless.default.svc.cluster.local:8848 中的default代表的是这个Pod所在的名空间名称,如果没有指定命名空间则写default即可

Ingress

image-20210609161022361

Nacos服务的Ingress配置。

域名为:k8snacos.kwrd.mobi

服务端口:8848

Application nacos.yaml

kubectl apply -f nacos.yaml

Visit WEB

http://k8snacos.kwrd.mobi/nacos/

image-20210609161054499

6.3.3 Service Registration

application.yaml configuration file

image-20210609161112941

If the Naocs connection address is a domain name, the port must be added, otherwise the connection will fail

image-20210609161131272

If the above registration is unsuccessful, you can try this blog method: https://blog.csdn.net/fsjwin/article/details/110217895