Nacos 介绍

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

Nacos 关键特性:

  1. 服务发现和服务健康监测
  2. 动态配置服务
  3. 动态 DNS 服务
  4. 服务及其元数据管理

Nacos 架构

image.png
NamingService:命名服务,注册中心核心接口
ConfigService:配置服务,配置中心核心接口
open api 文档

Nacos Server 部署

单机部署

准备安装包并解压

  1. [root@zhangrenkun-db app]# ll
  2. 总用量 79120
  3. drwxr-xr-x. 5 root root 72 2 17 19:39 nacos
  4. -rw-------. 1 root root 79052411 2 17 19:30 nacos-server-1.4.1.tar.gz

进入 nacos 目录

[root@zhangrenkun-db app]# cd nacos
[root@zhangrenkun-db nacos]# ll
总用量 24
drwxr-xr-x. 2 root root     82 2月  17 19:39 bin
drwxr-xr-x. 2  502 games   205 1月  15 2021 conf
-rw-r--r--. 1  502 games 16583 12月 15 2020 LICENSE
-rw-r--r--. 1  502 games  1305 5月  14 2020 NOTICE
drwxr-xr-x. 2 root root     30 2月  17 19:38 target

单机启动,执行命令

bin/startup.sh -m standalone

测试是否启动成功(注:防火墙是否开启),访问http://ip:8848/nacos,默认用户名/密码:nacos/nacos
image.png
image.png

集群模式

单机搭建伪集群模式

创建集群目录,复制 nacos 安装包,分别为 nacos8849,nacos8850,nacos8851

[root@zhangrenkun-db nacos-cluster]# ll
总用量 0
drwxr-xr-x. 5 root root 72 2月  17 21:51 nacos8849
drwxr-xr-x. 5 root root 72 2月  17 21:54 nacos8850
drwxr-xr-x. 5 root root 72 2月  17 21:54 nacos8851

以 nacos8849 为例,修改 conf/application.properties 的配置,使用外置数据源

### 使用外置 mysql 数据源
spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:(数据库连接自行配置)
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=nacos
db.password.0=nacos

修改 conf/cluster.conf.example 为cluster.conf,配置节点

#it is ip
#配置剩下节点 ip/端口 即可
192.168.16.101:8847
192.168.16.102
192.168.16.103

nacos8850,nacos8851 按同样方式配置即可

创建 mysql 数据库,sql 文件 conf/nacos-mysql.sql

[root@zhangrenkun-db conf]# ll
-rw-r--r--. 1 502 games 10660 12月 24 2020 nacos-mysql.sql

修改启动脚本的 jvm 参数

#===========================================================================================
# JVM Configuration
#===========================================================================================
if [[ "${MODE}" == "standalone" ]]; then
    JAVA_OPT="${JAVA_OPT} -Xms512m -Xmx512m -Xmn256m"
    JAVA_OPT="${JAVA_OPT} -Dnacos.standalone=true"
else

分别启动各个节点

bin/startup.sh

同样的方式进行测试;在控制台可观察到节点状态
image.png

prometheus + grafana 监控 nacos

nacos 0.8.0 版本完善了监控系统,支持通过暴露 metrics 数据接入第三方监控系统监控 nacos 运行状态https://nacos.io/zh-cn/docs/monitor-guide.html

  1. 暴露 metrics 数据

    management.endpoints.web.exposure.include=*
    

    测试地址:http://ip:8848/nacos/actuator/prometheus

  2. 修改配置文件prometheus.yml 采集 nacos metrics 数据

    metrics_path: '/nacos/actuator/prometheus'
    static_configs:
    - targets: ['{ip1}:8848','{ip2}:8848','{ip3}:8848']
    

    启动 prometheus 服务

    prometheus.exe --config.file=prometheus.yml
    

    测试地址:http://ip:9090/graph

  3. grafana 展示 metrics 数据

测试地址:http://ip:3000/
image.png

Nacos 注册中心

服务注册:nacos client 会通过发送 rest 请求的方式向 nacos server 注册自己的服务,提供自身的元数据,es:ip 地址、端口等信息;nacos server 接收到注册请求后,就会把这些元数据信息存储在一个双层的内存 map 中
服务心跳:在服务注册后,nacos client 会维护一个定时心跳来持续通知 nacos server,说明服务一直处于可用状态,防止被剔除;默认 5s 发送一次心跳
服务同步:nacos server 集群之间会互相同步服务实例,用来保证服务信息的一致性
服务发现:服务消费者在调用服务提供者的服务时,会发送一个 rest 请求给 nacos server,获取上面注册的服务清单,并缓存在 nacos client 本地,同时会在 nacos client 本地开启一个定时任务,定时拉取服务端最新的注册表信息更新到本地缓存
服务健康检查:nacos server 会开启一个定时任务用来检查注册服务实例的健康情况,对于超过 15s 没有收到客户端心跳的实例会将它的 healthy 属性设置为 false;若某个实例超过 30s 没有收到心跳,直接剔除该实例

搭建 nacos-client 服务

  1. 引入依赖

父 pom 中支持spring cloud & spring cloud alibaba

<dependencyManagement>
    <dependencies>
        <!--引入springcloud的版本-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>

    </dependencies>

当前项目 pom 中引入

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. application.properties 配置

    server.port=8002
    #微服务名称
    spring.application.name=service-user
    #配置 Nacos server 的地址
    

    nacos 更多配置

  2. 启动 SpringBoot 应用,nacos 控制台查看是否注册成功

image.png

Nacos & Ribbon & Feign 核心微服务架构图

微服务组件 Nacos - 图7

架构原理

  1. 微服务系统在启动时将自己注册到服务注册中心,同时对外发布 Http 接口供其他系统调用(一般都是基于 Spring MVC)
  2. 服务消费者基于 Feign 调用服务提供者对外发布的接口,先对调用的本地接口加上注解@FeignClient,Feign 会针对加了该注解的接口生成动态代理,服务消费者针对 Feign 生成的动态代理去调用方法时,会在底层生成 Http 协议格式的请求
  3. Feign 最终会调用 Ribbon 从本地的 Nacos 注册表的缓存里根据服务名取出服务提供在机器的列表,然后进行负载均衡并选择一台机器,对选出的机器 IP 和端口拼接之前生成的 url 请求,生成调用的 Http 接口地址,最后基于 HTTPClient 调用请求

Nacos 架构图

微服务组件 Nacos - 图8

Nacos 服务注册表结构

Map>

微服务组件 Nacos - 图9

Nacos 源码架构图

微服务组件 Nacos - 图10

Nacos 配置中心

配置中心官方文档

Nacos 提供用于存储配置和其他元数据的 key-value 存储,为分布式系统中的外部化配置提供服务端和客户端支持;使用 Spring Cloud Alibaba Nacos Config,可在 Nacos Server 集中管理应用的外部属性配置

配置应用

模拟配置:
image.png
image.png
模拟搭建服务:引入依赖

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

添加 bootstrap.properties:

spring.application.name=nacos-config
# 配置中心地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

# dataid 为 yaml 的文件扩展名配置方式
# `${spring.application.name}.${file-extension:properties}`
spring.cloud.nacos.config.file-extension=yaml
#profile粒度的配置   `${spring.application.name}-${profile}.${file-extension:properties}`

Config 相关配置

Nacos 数据模型 Key 由三元组唯一确定,Namespace 默认是空串,公共命名空间 public(默认),分组默认 DEFAULT_GROUP

支持配置的动态更新

@SpringBootApplication
public class NacosConfigApplication {

    public static void main(String[] args) throws InterruptedException {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);

         while(true) {
        //当动态配置刷新时,会更新到 Enviroment中,因此这里每隔一秒中从Enviroment中获取配置
         String userName = applicationContext.getEnvironment().getProperty("common.name");
        String userAge = applicationContext.getEnvironment().getProperty("common.age");
        System.err.println("common name :" + userName + "; age: " + userAge);
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

支持 profile 粒度的配置

spring-cloud-starter-alibaba-nacos-config 在加载配置的时候,不仅仅加载了以 dataid 为${spring.application.name}.${file-extension:properties}为前缀的基础配置,还加载了 dataid 为${spring.application.name}-${profile}.${file-extension:properties}的基础配置;在日常开发中若遇到多套环境下的不同配置,可通过 Spring 提供的${spring.profiles.active}来配置:

spring.profiles.active=dev

支持自定义 namespace 的配置

用于进行租户粒度的配置隔离;不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置;在没有明确指定${spring.cloud.nacos.config.namespace}配置的情况下,默认使用 Public 这个 namespace;若需要使用自定义的命名空间,可通过配置实现:

spring.cloud.nacos.config.namespace=71bb9785-231f-4eca-b4dc-6be446e12ff8

支持自定义 Group 的配置

Group是组织配置的维度之一;通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集;当在 Nacos 上创建一个配置时,若未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP ;在没有明确指定${spring.cloud.nacos.config.group} 配置的情况下,默认是DEFAULT_GROUP ;若需要自定义自己的 Group,可以通过以下配置来实现:

spring.cloud.nacos.config.group=DEVELOP_GROUP

@RefreshScope

@Value注解可以获取配置中心的值,但是无法动态感知修改后的值,需要利用@RefreshScope注解或@NacosValue注解:

@RestController
@RefreshScope
public class TestController {

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

    @NacosValue("${common.name}")
    private String name;

    @GetMapping("/common")
    public String hello() {
        return age;
    }
}

Nacos 配置中心源码分析

配置中心源码流程图