Spring Cloud Alibaba 实战(二)Nacos篇

8,854 阅读8分钟

白菜Java自习室 涵盖核心知识

Spring Cloud Alibaba 实战(一)准备篇
Spring Cloud Alibaba 实战(二)Nacos篇
Spring Cloud Alibaba 实战(三)Sentinel篇
Spring Cloud Alibaba 实战(四)Oauth2篇
Spring Cloud Alibaba 实战(五)Zuul篇
Spring Cloud Alibaba 实战(六)RocketMQ篇
Spring Cloud Alibaba 实战(七)Seata篇
Spring Cloud Alibaba 实战(八)SkyWalking篇

项目 GitHub 地址:github.com/D2C-Cai/her…

1. Nacos 简介

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。 Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

  • 服务发现和服务健康监测

Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDK、OpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODO 或HTTP&API查找和发现服务。

Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。

  • 动态配置服务

动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。

动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。

  • 动态 DNS 服务

动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。

Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表.

  • 服务及其元数据管理

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

2. 使用 Docker 快速搭建 Nacos 1.4

  1. 从 git 上 clone 项目:
git clone https://github.com/nacos-group/nacos-docker.git
  1. clone 完成后,进入 naocs-docker 目录
cd nacos-docker/example

注意在这个目录下,有一些可供我们使用的 docker-compose 脚本,如何选择呢?

Nacos支持三种部署模式:

  • 单机模式 - 用于测试和单机试用(单机模式支持mysql)。
  • 集群模式 - 用于生产环境,确保高可用。
  • 多集群模式 - 用于多数据中心场景。

为了配置简便,立即可用,我们里选择单机部署模式,而且不用mysql,来看下脚本内容。

standalone-derby.yaml

version: "2"
services:
  nacos:
    image: nacos/nacos-server:latest
    container_name: nacos-standalone
    environment:
    - PREFER_HOST_MODE=hostname
    - MODE=standalone
    volumes:
    - ./standalone-logs/:/home/nacos/logs
    - ./init.d/custom.properties:/home/nacos/init.d/custom.properties
    ports:
    - "8848:8848"
  prometheus:
    container_name: prometheus
    image: prom/prometheus:latest
    volumes:
      - ./prometheus/prometheus-standalone.yaml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    depends_on:
      - nacos
    restart: on-failure
  grafana:
    container_name: grafana
    image: grafana/grafana:latest
    ports:
      - 3000:3000
    restart: on-failure
  1. 执行 standalone-derby.yaml 脚本启动容器
docker-compose -f standalone-derby.yaml up
  1. 用于后期其他需要,务必开启 firewall 防火墙端口
firewall-cmd --zone=public --add-port=8848/tcp --permanent
firewall-cmd --reload
  1. 登录 Nacos 控制台,默认用户名为 nacos,密码为 nacos
http://(安装Nacos机器的IP):8848/nacos

Nacos 控制台里有好多功能,如何使用呢?这里我们先不急,先来配置Spring Boot项目客户端。

3. 在 Spring 项目中引入 Nacos 客户端

这里有两部分内容 Nacos Discovery(服务发现)和 Nacos Config(配置管理)

3.1. 启动服务发现

  1. 添加 pom 文件依赖
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
  1. 在 application.yml 添加配置
server:
  port: 8080
  
spring:
  application:
    name: (项目名称)-service

  cloud:
    nacos:
      discovery:
        server-addr: (安装Nacos机器的IP):8848
  1. 添加注解 @EnableDiscoveryClient 开启服务注册发现功能
@EnableDiscoveryClient
@SpringBootApplication
public class TestServiceApplication {

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

}

3.2. 启动配置管理

  1. 添加 pom 文件依赖
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
  1. 在 bootstrap.yml 添加配置

注意这里看清楚是 bootstrap.yml,请读者自行百度 Spring Boot 项目 application.yml 和 bootstrap.yml 的区别。

spring:
  profiles:
    active: dev
  application:
    name: (项目名称)-service

  cloud:
    nacos:
      config:
        server-addr: (安装Nacos机器的IP):8848
        file-extension: properties

说明:之所以需要配置 spring.application.name ,是因为它是构成 Nacos 配置管理 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.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

Nacos配置到这里,我们已经能启动自己的项目了,启动的项目会显示在控制台的 服务列表 里:

4. Nacos 控制台配合项目实战

4.1. 命名空间

命名空间 用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

Nacos 基于 Namespace 帮助用户逻辑隔离多个命名空间,这可以帮助用户更好的管理测试、预发、生产等多环境服务和配置,让每个环境的同一个配置(如数据库数据源)可以定义不同的值。

  1. 我们添加一个名字叫 dev 的命名空间(默认有个 public)

  1. 此时,配置列表里就会多出一个命名空间为 dev 的配置分组,不同环境分出不同配置

Spring 项目若要读取对应的配置,则对应修改我们的 bootstrap.yml 配置:

spring:
  profiles:
    active: dev
  application:
    name: (项目名称)-service

  cloud:
    nacos:
      config:
      	namespace: b96b8faf-3f04-4f6f-a321-aae6f0a2414b
        server-addr: (安装Nacos机器的IP):8848
        file-extension: properties

4.2. 动态配置

动态配置 系统配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动。一个具体的可配置的参数与其值域,通常以 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 配置。
  1. 我们选择 dev 命名空间,添加一个 Data ID 为 gateway-service-dev.properties 的配置项(按照上文的规则${prefix}-${spring.profiles.active}.${file-extension}),Group 设置为 README_GROUP
mine.name=baicai
mine.age=18

  1. 对应修改我们的 bootstrap.yml 配置
spring:
  profiles:
    active: dev
  application:
    name: (项目名称)-service

  cloud:
    nacos:
      config:
      	group: README_GROUP
      	namespace: b96b8faf-3f04-4f6f-a321-aae6f0a2414b
        server-addr: (安装Nacos机器的IP):8848
        file-extension: properties
  1. 在我们的项目中使用 @RefreshScope 和 @Value 来读取对应的配置(冒号后边的是默认值)
@RefreshScope
@RestController
@RequestMapping("/config")
public class ConfigController {

    @Value("${mine.name:none}")
    private String name;
    @Value("${mine.age:0}")
    private String age;

    @RequestMapping("/get")
    public String get() {
        return name + ": " + age;
    }

}
  1. 访问下这个请求,看下配置内容是不是已经同步到项目中
#### 配置测试
GET http://localhost:8080/config/get
Accept: */*
Cache-Control: no-cache

请求得到结果:

baicai: 18

我们去修改下配置的内容,看看是否会实时同步到项目中:

mine.name=baicai-2
mine.age=18-2

请求得到结果:

baicai-2: 18-2

可以清晰的看见项目中的日志:

2021-02-07 16:04:29.855  INFO 23972 --- [21-aae6f0a2414b] o.s.c.e.event.RefreshEventListener       : Refresh keys changed: [mine.name, mine.age]
2021-02-07 16:04:29.856  INFO 23972 --- [21-aae6f0a2414b] c.a.nacos.client.config.impl.CacheData   : [fixed-192.168.138.131_8848-b96b8faf-3f04-4f6f-a321-aae6f0a2414b] [notify-ok] dataId=gateway-service-dev.properties, group=README_GROUP, md5=f9c5b973de2fc78a9314efdef195dfad, listener=com.alibaba.cloud.nacos.refresh.NacosContextRefresher$1@2279ad91 
2021-02-07 16:04:29.856  INFO 23972 --- [21-aae6f0a2414b] c.a.nacos.client.config.impl.CacheData   : [fixed-192.168.138.131_8848-b96b8faf-3f04-4f6f-a321-aae6f0a2414b] [notify-listener] time cost=1719ms in ClientWorker, dataId=gateway-service-dev.properties, group=README_GROUP, md5=f9c5b973de2fc78a9314efdef195dfad, listener=com.alibaba.cloud.nacos.refresh.NacosContextRefresher$1@2279ad91 
  1. 如果我这次改动的配置文件内容是错的,我又不太记得上次正确的是什么了,我想恢复上次的内容怎么办

没关系,nacos 为我们提供了 30 天的配置文件修改记录:

我们马上来尝试回滚下配置:

请求得到结果:

baicai: 18

终于,正确的配置又回来了。

4.3. 服务管理

服务管理 开发者或者运维人员往往需要在服务注册后,通过友好的界面来查看服务的注册情况,包括当前系统注册的所有服务和每个服务的详情。并在有权限控制的情况下,进行服务的一些配置的编辑操作。Nacos在这个版本开放的控制台的服务发现部分,主要就是提供用户一个基本的运维页面,能够查看、编辑当前注册的服务。

  1. 查看服务的详情参数

  1. 服务流量权重支持、服务元数据管理、服务优雅上下线

  • 服务流量权重支持

Nacos 为用户提供了流量权重控制的能力,同时开放了服务流量的阈值保护,以帮助用户更好的保护服务服务提供者集群不被意外打垮。如下图所以,可以点击实例的编辑按钮,修改实例的权重。如果想增加实例的流量,可以将权重调大,如果不想实例接收流量,则可以将权重设为0。

  • 服务元数据管理

Nacos提供多个维度的服务元数据的暴露,帮助用户存储自定义的信息。这些信息都是以K-V的数据结构存储,在控制台上,会以k1=v1,k2=v2这样的格式展示。类似的,编辑元数据可以通过相同的格式进行。例如服务的元数据编辑,首先点击服务详情页右上角的“编辑服务”按钮,然后在元数据输入框输入:version=1.0,env=prod。

  • 服务优雅上下线

Nacos还提供服务实例的上下线操作,在服务详情页面,可以点击实例的“上线”或者“下线”按钮,被下线的实例,将不会包含在健康的实例列表里。

4.4. 登录管理

  1. 创建新用户

  1. 用户绑定角色

  1. 角色添加权限

Spring Cloud Alibaba 实战(一)准备篇
Spring Cloud Alibaba 实战(二)Nacos篇
Spring Cloud Alibaba 实战(三)Sentinel篇
Spring Cloud Alibaba 实战(四)Oauth2篇
Spring Cloud Alibaba 实战(五)Zuul篇
Spring Cloud Alibaba 实战(六)RocketMQ篇
Spring Cloud Alibaba 实战(七)Seata篇
Spring Cloud Alibaba 实战(八)SkyWalking篇

项目 GitHub 地址:github.com/D2C-Cai/her…