前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文读懂Nacos注册中心

一文读懂Nacos注册中心

原创
作者头像
Blue_007
修改2023-11-02 22:21:15
5820
修改2023-11-02 22:21:15
举报
文章被收录于专栏:代码生涯代码生涯

🎈 一、概述

Nacos 官网地址:https://nacos.io

我们先进入它的官网看看,官网说的很清楚了Nacos的2个核心能力:

  • 服务发现
  • 配置管理

所以Nacos可以作为:

  • 服务注册中心
    • Nacos 支持基于 DNS 和基于 RPC 的服务发现
    • 服务提供者使用原生SDK、OpenApi注册 Service 后,服务消费者可以使用DNS TODO或HTTP&API查找和发现服务
    • Nacos提供对服务的健康监测,阻止向不健康的服务或者实例发送请求
  • 配置中心
    • 动态配置服务可以让使用者以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置
    • 动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷
    • 配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易

其他:

Nacos支持AP和CP模式的切换

C是所有节点在同一时间看到的数据是一致的;而A的定义是所有的请求都会收到响应。

何时选择使用何种模式?

—般来说,如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如Spring cloud和Dubbo服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。

如果需要在服务级别编辑或者存储配置信息,那么CP是必须,K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。

切换命令:

代码语言:shell
复制
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP

🎆 二、安装Nacos-server

🎇 2.1 下载编译后压缩包

下载地址: 最新稳定版本 下载nacos-server-$version.zip

🧨 2.2 启动服务

代码语言:shell
复制
# 进入nacos下的bin目录
cd nacos/bin

Nacos支持三种服务部署方式

  1. 单机模式:用户测试和单机使用
  2. 集群模式:生产环境使用,保证服务的高可用
  3. 多集群模式: 用于多数据中心场景

这里就使用单机模式了

👝 Linux/Unix/Mac

启动命令(standalone代表着单机模式运行,非集群模式):

代码语言:shell
复制
sh startup.sh -m standalone

如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:

代码语言:shell
复制
bash startup.sh -m standalone

🎯 Windows

启动命令(standalone代表着单机模式运行,非集群模式):

代码语言:shell
复制
startup.cmd -m standalone

双击 startup.cmd 文件也行

✨ 2.3 访问Nacos-server

浏览器访问 127.0.0.1:8848 就能看到Nacos的Web页面了,默认的账号密码都是 nacos

🎉 三、nacos的注册中心

🎊 3.1 创建服务提供者模块

新建module:nacos-provider

pom.xml文件如下(注意spring-boot-starter-web也一定要引入,因为有被使用):

代码语言:html
复制
<?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.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.apps</groupId>
    <artifactId>nacos-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacos-provider</name>

    <properties>
        <java.version>1.8</java.version>
        <nacos.version>2.2.6.RELEASE</nacos.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- Web启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Nacos依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${nacos.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>

application.yml文件如下:

代码语言:yaml
复制
server:
  port: 7001

spring:
  application:
    # 微服务名称
    name: service-provider
  cloud:
    nacos:
      discovery:
        # nacos服务发现地址, 多个地址使用逗号隔开, 注意: 不用添加http(s)://
        server-addr: 192.168.6.206:8848

主启动类:

(@EnableDiscoveryClient) SpringCloud的服务注册发现标签,让注册中心能够发现,扫描到该服务

代码语言:java
复制
package com.apps;

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

@SpringBootApplication
@EnableDiscoveryClient
public class NacosDemoApplication {

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

}

编写控制器:

代码语言:java
复制
package com.apps.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Blue 2113438464@qq.com
 * @ClassName ProviderController
 * @Description 作用
 * @date 2022/6/13 9:49
 * @Version 1.0
 */
@RestController
@RequestMapping("/provider")
public class ProviderController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/info")
    public String getPayment(){
        return "nacos注册表,服务器端口:" + port ;
    }

}

然后启动该模块,在nacos控制台就能看到该实例已经注册到nacos:

🎃 3.2 创建服务消费者模块

新建module:nacos-consumer

pom.xml文件如下(注意spring-boot-starter-web也一定要引入,因为有被使用):

代码语言:html
复制
<?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.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.apps</groupId>
    <artifactId>nacos-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacos-consumer</name>

    <properties>
        <java.version>1.8</java.version>
        <nacos.version>2.2.6.RELEASE</nacos.version>
    </properties>

    <dependencies>
        <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>
        <!-- Web启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Nacos依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${nacos.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
        </plugins>
    </build>

</project>

application.yml文件如下:

代码语言:yaml
复制
server:
  port: 10083

spring:
  application:
    name: service-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.6.206:8848

# 消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://service-provider

主启动类:

代码语言:java
复制
package com.apps;

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

@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApplication {

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

}

配置类:

代码语言:java
复制
package com.apps.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;


/**
 * @author Blue 2113438464@qq.com
 * @ClassName JavaConfig
 * @Description 作用
 * @date 2022/6/13 10:50
 * @Version 1.0
 */
@Component
public class JavaConfig {

    // @LoadBalanced这个注解是让 RestTemplate 开启负载均衡的能力
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

控制器:

代码语言:java
复制
package com.apps.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author Blue 2113438464@qq.com
 * @ClassName controller
 * @Description 作用
 * @date 2022/6/13 10:56
 * @Version 1.0
 */
@RestController
@RequestMapping("consumer")
public class ConsumerController {

    @Value("${service-url.nacos-user-service}")
    private String serviceUrl;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/info")
    public String getClientServerResult(){
        return restTemplate.getForObject(serviceUrl + "/provider/info", String.class);
    }

}

然后启动消费者模块,在nacos控制台可以看到服务列表

然后启动消费者模块,在nacos控制台可以看到服务列表,便可以使用服务了,当前我们可以启动多个服务名相同服务实例来使用Nacos的负载均衡。

🎄 3.3 Nacos的负载均衡

nacos支持负载均衡是因为spring-cloud-starter-alibaba-nacos-discovery内含netflix-ribbon包(这里要感谢技术大牛浩哥的指导)。

为了省事,我们可以直接copy一个provider进行启动

修改名字,好区别。并且指定服务端口,这里指定权重更高,所以优先VM的参数

copy完成后,启动。就有两个相同服务名的实例了

然后通过consumer的AIP访问provider的接口,通过打印可以知道是轮询访问10001/10002

🎋 四、nacos作为配置中心

🎍 4.1 创建配置模块

新建module:nacos-config

pom.xml文件如下(注意这里引入的是spring-cloud-starter-alibaba-nacos-config):

代码语言:html
复制
<?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.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.apps</groupId>
    <artifactId>nacos-config</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacos-config</name>
    <description>nacos-config</description>

    <properties>
        <java.version>1.8</java.version>
        <nacos.version>2.2.6.RELEASE</nacos.version>
    </properties>

    <dependencies>
        <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>

        <!--nacos-config-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${nacos.version}</version>
        </dependency>
        <!-- Web启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

nacos和springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动

springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application。所以我们拉取配置需要写在bootstrap.yml文件中,启动完bootstrap.yml把相关配置拉取下来后才能正常启动项目。

配置bootstrap.yml文件

代码语言:yaml
复制
server:
  port: 3377
spring:
  application:
    name: nacos-config
  cloud:
    nacos:
      config:
        server-addr: 192.168.6.206:8848   # nacos本地服务器地址
        file-extension: yaml   # 配置文件的格式,默认properties
        group: DEFAULT_GROUP  # 分组,默认DEFAULT_GROUP

配置application.yml文件

代码语言:html
复制
spring:
  profiles:
    active: dev

🎎 4.2 在nacos控制台增加配置信息

前面我们在bootstrap.yml文件中配置了spring.application.name,是因为它是构成 Nacos 配置管理 dataId字段的一部分(是什么dataId等一些技术名词我会在文章后面讲解)。

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

代码语言:shell
复制
${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 类型。

最后公式:

代码语言:shell
复制
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

接下来在nacos控制台新增配置

保存后,创建控制器

代码语言:java
复制
package com.apps.controller;

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;

/**
 * @author Blue 2113438464@qq.com
 * @ClassName NacosConfigController
 * @Description 作用
 * @date 2022/6/13 16:58
 * @Version 1.0
 */
@RefreshScope
@RestController
public class NacosConfigController {

    @Value("${user.name}")
    private String name;
    @Value("${user.age}")
    private String name;

    @RequestMapping(value = "config/info")
    public String getConfigValue() {
        System.err.println("user name :" +name+"; age: "+age);
        return this.name + this.age;
    }

}

启动项目,访问请求,控制台打印

nacos控制台修改yml参数后(也可以发送Open API修改),又访问请求,配置信息就修改了。

🎏 五、名词理念

👕 5.1 namespace和group和dataId三者的关系

三个东西是为了解多项目多环境的问题。

实际开发中,通常一个系统会准备

  • dev开发环境
  • test测试环境
  • prod生产环境

如何保证指定环境启动时服务能正确读取到Nacos上相应环境的配置文件呢?

一个大型分布式微服务系统会有很多微服务子项目,每个微服务项目又都会有相应的开发环境、测试环境、预发环境、正式环境…那怎么对这些微服务配置进行管理呢?


nacos默认的namespace是public,默认的group是DEFAULT_GROUP


类似Java里面的package名和类名,最外层的namespace是可以用于区分部署环境的,Group和DatalD逻辑上区分两个目标对象。

  • Nacos默认的Namespace是public,Namespace主要用来实现隔离。

比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的Namespace之间是隔离的。

  • Group默认是DEFAULT_GROUP,Group可以把不同的微服务划分到同一个分组里面去
  • Service就是微服务:一个Service可以包含多个Cluster (集群),Cluster是对指定微服务的一个虚拟划分。 比方说为了容灾,将Service微服务分别部署在了杭州机房和广州机房,这时就可以给杭州机房的Service微服务起一个集群名称(HZ) ,给广州机房的Service微服务起一个集群名称(GZ),还可以尽量让同一个机房的微服务互相调用,以提升性能。
  • 最后是Instance,就是微服务的实例

我们可以在nacos控制台创建namespace和group。

创建dev和test的namespace


回到配置列表,就能看到我们创建的namespace


分别在test和dev的namespace里新建配置文件


在bootstrap.yml中指定group和namespace就可以获取不同的配置文件了。(记住dataId的生成规则)

代码语言:yaml
复制
spring:
  application:
    name: cloud-nacos-config
  cloud:
    nacos:
      config:
        server-addr: localhost:8848   # nacos本地服务器地址
        file-extension: yaml   # 配置文件的格式,默认properties
        group: TEST_GROUP  # 分组,默认DEFAULT_GROUP
        # group: DEV_GROUP
        namespace: 155a7fd7-6834-4787-80f7-35f56dd9f8fb
        # namespace: 2f42a525-6d50-45dc-8ed1-d474fff7ce42

🎑 5.2 Nacos配置管理模型

对于Nacos配置管理,通过Namespace、group、Data ID能够定位到一个配置集

配置集(Data ID)

在系统中,一个配置文件通常就是一个配置集,一个配置集可以包含了系统的各种配置信息,例如一个配置集可能包含了数据源、线程池、日志级别等配置项。每个配置集都可以定义一个有意义的名称,就是配置集的ID即Data ID


配置项

就是我们的配置内容

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


配置分组(Group)

配置分组是对配置集进行分组,通过一个有意义的字符串(如Buy或Trade ) 来表示

不同的配置分组下可以有相同的配置集( DataID)。当您在Nacos上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用DEFAULT_GROUP。配置分组的常见场景:可用于区分不同的项目或应用,例如学生管理系统的配置集可以定义一个group为:STUDENT_GROUP


命名空间(Namespace)

命名空间( namespace )可用于进行不同环境的配置隔离

例如可以隔离开发环境、测试环境和生产环境,因为它们的配置可能各不相同,或者是隔离不同的用户,不同的开发人员使用同一个nacos管理各自的配置,可通过namespace隔离。

不同的命名空间下,可以存在相同名称的配置分组(Group)或配置集。


获取某配置集的代码:需要指定

  1. nacos服务地址,必须指定
  2. namespace,不指定默认为public
  3. group,不指定默认为DEFAULT_GROUP
  4. dateId,必须指定

🎨 六、最后

如果您对本文有任何疑问或需要帮助,请在评论区留言,我会尽力解答。如果本文对您有帮助,请给个赞以示支持,非常感谢!💗

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🎈 一、概述
  • 🎆 二、安装Nacos-server
    • 🎇 2.1 下载编译后压缩包
      • 🧨 2.2 启动服务
        • 👝 Linux/Unix/Mac
        • 🎯 Windows
      • ✨ 2.3 访问Nacos-server
      • 🎉 三、nacos的注册中心
        • 🎊 3.1 创建服务提供者模块
          • 🎃 3.2 创建服务消费者模块
            • 🎄 3.3 Nacos的负载均衡
            • 🎋 四、nacos作为配置中心
              • 🎍 4.1 创建配置模块
                • 🎎 4.2 在nacos控制台增加配置信息
                • 🎏 五、名词理念
                  • 👕 5.1 namespace和group和dataId三者的关系
                    • 🎑 5.2 Nacos配置管理模型
                    • 🎨 六、最后
                    相关产品与服务
                    负载均衡
                    负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档