Nacos 笔记

Nacos 笔记

本文档基于v2.0.3进行整理。

1. Nacos简介

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

1.1 主流配置中心对比

目前市面上用的比较多的配置中心有:Spring Cloud Confifig、Apollo、Nacos和Disconf等。 由于Disconf不再维护,下面主要对比一下Spring Cloud Confifig、Apollo和Nacos。

从配置中心角度来看,性能方面Nacos的读写性能最高,Apollo次之,Spring Cloud Confifig依赖Git场景不适合开 放的大规模自动化运维API。功能方面Apollo最为完善,nacos具有Apollo大部分配置管理功能,而Spring Cloud Confifig不带运维管理界面,需要自行开发。Nacos的一大优势是整合了注册中心、配置中心功能,部署和操作相比 Apollo都要直观简单,因此它简化了架构复杂度,并减轻运维及部署工作。

综合来看,Nacos的特点和优势还是比较明显的,下面我们一起进入Nacos的世界。

1.2 主流注册中心对比

目前市面上用的比较多的服务发现中心有:Nacos、Eureka、Consul和Zookeeper。

image-20210811164951654

1.3 Nacos特性

Nacos主要提供以下四大功能:

  1. 服务发现与服务健康检查

    Nacos使服务更容易注册,并通过DNS或HTTP接口发现其他服务,Nacos还提供服务的实时健康检查,以防止向不健康的主机或服务实例发送请求。

  2. 动态配置管理

    动态配置服务允许您在所有环境中以集中和动态的方式管理所有服务的配置。Nacos消除了在更新配置时重新部署应用程序,这使配置的更改更加高效和灵活。

  3. 动态DNS服务

    Nacos提供基于DNS 协议的服务发现能力,旨在支持异构语言的服务发现,支持将注册在Nacos上的服务以域名的方式暴露端点,让三方应用方便的查阅及发现。

  4. 服务和元数据管理

    Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略。

这里动态配置管理的特性说明了Naocs的配置管理能力。

2. 安装启动

安装启动

支持外部 MySQL

单机模式时nacos默认使用嵌入式数据库实现数据的存储,若想使用外部mysql存储nacos数据,需要进行以下步骤:

  • 初始化mysql数据库,新建数据库nacos_confifig,数据库初始化文件:${nacoshome}/conf/nacos-mysql.sql
  • 修改${nacoshome}/conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
spring.datasource.platform=mysql 
db.num=1 
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_config? characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true 
db.user=nacos_devtest 
db.password=youdontknow

注意:支持MySQL 8需要添加插件。

3. 配置管理

3.1 什么是配置中心

什么是配置?

应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数据库连接参数、启动参数等。

配置主要有以下几个特点:

  • 配置是独立于程序的只读变量

    • 配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置;
  • 配置伴随应用的整个生命周期

    • 配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。比如:启动时需要读取服务的端口号、系统在运行过程中需要读取定时策略执行定时任务等。
  • 配置可以有多种加载方式

    • 常见的有程序内部hard code,配置文件,环境变量,启动参数,基于数据库等
  • 配置需要治理

    • 同一份程序在不同的环境(开发,测试,生产)、不同的集群(如不同的数据中心)经常需要有不同的配置,所以需要有完善的环境、集群配置管理

什么是配置中心?

总得来说,配置中心就是一种统一管理各种应用配置的基础服务组件。

在传统巨型单体应用纷纷转向细粒度微服务架构的历史进程中,配置中心是微服务化不可缺少的一个系 统组件,在这种背景下中心化的配置服务即配置中心应运而生,一个合格的配置中心需要满足如下特性:

  • 配置项容易读取和修改
  • 分布式环境下应用配置的可管理性,即提供远程管理配置的能力
  • 支持对配置的修改的检视以把控风险
  • 可以查看配置修改的历史记录
  • 不同部署环境下应用配置的隔离性

3.2 Nacos 配置入门(Spring-Boot形式)

step1:使用Nacos的界面发布配置

image-20210809191741378

image-20210809191824668

step2:通过Nacos API获取配置

/**
 * 演示使用Nacos API 对配置中心数据进行增删改查的过程
 */
public class NacosApiDemo {
    public static void main(String[] args) throws NacosException, InterruptedException {
        String serverAddr = "localhost";
        String dataId = "application.yml";
        String group = "demo";
        String nameSpace = "6f97a206-ce19-44c2-85be-c601170d306e";
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        properties.put(PropertyKeyConst.NAMESPACE, nameSpace);
        ConfigService configService = NacosFactory.createConfigService(properties);

        // 启动的时候读取配置中心的配置
        String content = configService.getConfig(dataId, group, 5000);
        System.out.println("配置内容:");
        System.out.println(content);

        // 监听配置中心数据的变化
        configService.addListener(dataId, group, new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                System.out.println("recieve:" + configInfo);
            }

            @Override
            public Executor getExecutor() {
                return null;
            }
        });

        // 向数据中心推送数据,改变原有配置
        boolean isPublishOk = configService.publishConfig(dataId, group, "content");
        System.out.println(isPublishOk);

        //再次读取数据
        Thread.sleep(3000);
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);

        // 删除配置中心数据
        boolean isRemoveOk = configService.removeConfig(dataId, group);
        System.out.println(isRemoveOk);
        Thread.sleep(3000);

        // 再次读书数据
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        Thread.sleep(300000);

    }
}

3.3 Web界面基本使用

Nacos 配置管理模型

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

image-20210809200735604

配置集(Data ID)

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

配置项

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

配置分组(Group)

配置分组是对配置集进行分组,通过一个有意义的字符串(如 Buy 或 Trade )来表示,不同的配置分组下可以有 相同的配置集(Data ID)。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默 认采用 DEFAULT_GROUP 。配置分组的常见场景:可用于区分不同的项目或应用,例如:学生管理系统的配置集 可以定义一个group为:STUDENT_GROUP。

命名空间(Namespace)

命名空间(namespace)可用于进行不同环境的配置隔离。例如可以隔离开发环境、测试环境和生产环境,因为 它们的配置可能各不相同,或者是隔离不同的用户,不同的开发人员使用同一个nacos管理各自的配置,可通过 namespace隔离。不同的命名空间下,可以存在相同名称的配置分组(Group) 或 配置集。

最佳实践

Nacos抽象定义了Namespace、Group、Data ID的概念,具体这几个概念代表什么,取决于我们把它们看成什 么,这里推荐给大家一种用法,如下图:

image-20210809201209744

命名空间的管理

namespace 的设计是 nacos 基于此做多环境以及多租户(多个用户共同使用nacos)数据(配置和服务)隔离的。

  • 从一个租户(用户)的角度来看,如果有多套不同的环境,那么这个时候可以根据指定的环境来创建不同的 namespce,以此来实现多环境的隔离。例如,你可能有开发,测试和生产三个不同的环境,那么使用一套 nacos 集群可以分别建以下三个不同的 namespace。如下图所示:

    image-20210809203504494

  • 从多个租户(用户)的角度来看,每个租户(用户)可能会有自己的 namespace,每个租户(用户)的配置数据以及注 册的服务数据都会归属到自己的 namespace 下,以此来实现多租户间的数据隔离。例如超级管理员分配了三 个租户,分别为张三、李四和王五。分配好了之后,各租户用自己的账户名和密码登录后,创建自己的命名 空间。如下图所示:

    image-20210809203629892

Nacos界面使用(配置管理)

image-20210809205136793

上面监听查询的功能说下:可以通过IP地址查询,查询client端已经读取到的配置文件的MD5值,用这个MD5值和配置文件详情中的MD5值对比就可以知道客户端拿到的配置文件是不是最新的。

Spring-Cloud 整合Nacos

将演示如何使用 Spring Cloud Alibaba Nacos ConfifigSpring Cloud应用中集成Nacos,通过 Spring cloud原生方式快捷的获取配置内容。

Spring Cloud是什么:

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot 的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成 熟、经得起实际考验的服务框架组合起来,集成最多的组件要属Netflflix公司,通过Spring Boot风格进行再封 装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发 工具包。

Spring Cloud Alibaba Nacos Confifig是什么:

Spring Cloud Alibaba Nacos Confifig是Spring Cloud Alibaba的子项目,而Spring Cloud Alibaba是阿里巴巴公司提供的开源的基于Spring cloud的微服务套件合集,它致力于提供微服务开发的一站式解决方案,可以理解为spring cloud是一套微服务开发的 标准 ,spring cloud alibaba与spring cloud Netflflix是实现。使用 Spring Cloud Alibaba方案,开发者只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。

step1:添加依赖

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
         <version>2.2.6.RELEASE</version>
     </dependency>
</dependencies>

step2:添加配置(bootstrap.yml)

#日志配置
logging:
  config: classpath:logback-app.xml

#Server相关配置
server:
  port: ${port:9999}

#Spring相关配置
spring:
  application:
    name: cloud-app
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-exetension: yaml
        namespace: 6f97a206-ce19-44c2-85be-c601170d306e
        group: demo

在 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 类型。

step3:通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新

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

    @Value("${useLocalCache:false}")
    private boolean useLocalCache;

    @RequestMapping("/get")
    public boolean get() {
        return useLocalCache;
    }
}

自定义配置(data-id)

共享配置文件

  • 团队内部的项目共享配置文件
spring:
  application:
    name: server1
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.2:8848
        file-extension: yaml
        namespace: 6f97a206-ce19-44c2-85be-c601170d306e
        group: demo
        # 这边的shared-configs不能配置namespace,和上面的配置共享一个namespace,所以一般用于读取一个团队内部的共享文件
        shared-configs[0]:
         data-id: common.yaml
         refresh: true
         group: common
  • 一个项目有多个配置文件的情况
spring:
  application:
    name: server1
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.2:8848
        file-extension: yaml
        namespace: 6f97a206-ce19-44c2-85be-c601170d306e
        group: demo
        extensionConfigs[0]:
          data-id: jdbc.yaml
          refresh: true
          group: demo
        extensionConfigs[1]:
          data-id: o32.yaml
          refresh: true
          group: demo
        shared-configs[0]:
          data-id: common.yaml
          refresh: true
          group: common

配置文件优先级

假如依赖的配置文件有冲突。

主配置文件(通过nacos配置确定的配置文件)> 扩展配置1 > 扩展配置0 > 公共配置

4. 服务发现

微服务环境下,服务经常是多实例部署的。而且经常会增加实例或者下线实例,服务之前怎么互相感知,就是服务发现需要研究的问题。

总结一下,在微服务环境中,由于服务运行实例的网络地址是不断动态变化的,服务实例数量的动态变化 ,因此无 法使用固定的配置文件来记录服务提供方的网络地址,必须使用动态的服务发现机制用于实现微服务间的相互感知。各服务实例会上报自己的网络地址,这样服务中心就形成了一个完整的服务注册表,各服务实例会通过服务发现中心来获取访问目标服务的网络地址,从而实现服务发现的机制。

4.1 Nacos 服务发现快速入门

image-20210811171857774

采用Feign+Ribbon的整合方式,是由Feign完成远程调用的整个流程。而Feign集成了Ribbon,Feign使用Ribbon

完成调用实例的负载均衡。 (Feign做远程调用,Ribbon用来做负载均衡)

Ribbon 简介

Ribbon是一个客户端负载均衡器,它的责任是从一组实例列表中挑选合适的实例,如何挑选?取决于负载均衡策略

Ribbon核心组件IRule是负载均衡策略接口,它有如下实现:

image-20210811172445596

可通过下面方式在spring boot 配置文件中修改默认的负载均衡策略:

account‐service.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

account-service 是调用的服务的名称,后面的组成部分是固定的。

Feign介绍

Feign是Netflflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。Feign 的英文表意为“假装,伪装,变形”, 可以理解为将HTTP报文请求方式伪装为简单的java接口调用方式。

4.2 服务提供端代码

# Server相关配置
server:
  port: 18080

#Spring相关配置
spring:
  application:
    name: server1
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.2:8848

依赖:

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
     </dependency>
</dependencies>

启动服务端:

@SpringBootApplication
@EnableDiscoveryClient
public class CloudServer1 {

    private static Logger logger = LoggerFactory.getLogger(CloudServer1.class);

    public static void main(String[] args) {
        System.setProperty("nacos.logging.default.config.enabled","false");
        logger.info("CloudServer1 begin to start...");
        SpringApplication.run(CloudServer1.class, args);
        logger.info("CloudServer1 start success...");
    }
}

4.3 服务调用端代码

step1:添加依赖

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</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-openfeign</artifactId>
     </dependency>
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
     </dependency>
</dependencies>

step2:添加配置

server:
  port: 9999

#Spring相关配置
spring:
  application:
    name: cloud-comsumer
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.2:8848

step3:添加客户端调用

@FeignClient(name = "server1")
public interface ServerConsumerClient {

    @GetMapping("/echo/chen")
    String echoChen();

    @GetMapping("/echo/zhao")
    String echoZhen();
}

step4:启动应用

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class CloudApp {

    private static Logger logger = LoggerFactory.getLogger(CloudApp.class);

    public static void main(String[] args) {
        System.setProperty("nacos.logging.default.config.enabled","false");
        logger.info("app begin to start...");
        SpringApplication.run(CloudApp.class, args);
        logger.info("app start success...");
    }
}

Nacos 使用规范

  • 接入时必须填写用户密码

原理性文章

  • Nacos 客户端读取配置、更新配置、删除配置和监听服务端配置变化的原理;

  • Nacos 各个日志的功能;

  • 配置多个数据库的原理;

  • Nacos 接入用户时必须指定用户密码;

  • Nacos 用户权限管理。 --- https://www.cnblogs.com/yunqishequ/p/12720079.html 对服务发现有没有影响

参考

人生的主旋律其实是苦难,快乐才是稀缺资源。在困难中寻找快乐,才显得珍贵~
原文地址:https://www.cnblogs.com/54chensongxia/p/15115586.html