2.nacos服务配置中心

下面将研究以下几个问题:

  1. nacos的角色: nacos是如何工作的? 在集群中扮演什么样的角色?
  2. 修改nacos配置数据库: 我们在控制台配置的信息, 默认是写到nacos的默认数据库中, 不方便管理, 因此我们设置一个自己的数据库, 进行管理操作
  3. 在控制台配置nacos配置
  4. nacos配置管理的模型: 基本概念,namespace, group, data id及其用法
  5. 命名空间的管理, namespace的使用
  6. Nacos配置管理应用于分布式系统
  7. 7.Nacos集群部署

一. nacos的角色
在这里插入图片描述

这张图说明了nacos是一个单独的服务器, 用户修改或者发布配置信息, 会通知下游的服务器. 下游的服务器也可以根据一定的规则读取配置中心的配置信息.

让nacos成为spring cloud集群的一部分

  1. 启动nacos服务

  2. 将nacos纳为spring cloud微服务的一部分

  3. 将spring cloud其他应用服务注册到nacos上.

二. 修改nacos配置数据库

下面验证服务的可用性

1. 启动nacos

./startup.sh -m standalone

注意: 这里一定要单机模式启动, 默认是集群模式, 我们现在没有在集群中, 会报异常.

2 往配置中心发布配置

nacos是一个服务, 他对外也提供了很多接口, 其中一个是添加配置的接口. 我们模拟这个接口进行配置:

curl -X POST "http://localhost:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"

看到返回结果是true. 然后刷新控制台, 可以看到如下


在这里插入图片描述

3. 从配置中心获取配置

curl -X GET "http://localhost:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"
这个命令就是获取配置

在这里插入图片描述

获取helloworld内容

4. 改变nacos配置数据的存储位置

我们把配置信息添加到nacos, 那么,他是如何保存的呢? nacos某一个默认的自带数据库, 这个数据库不方便操作和查找. 因此我们将其替换为自己的mysql数据库

1. 准备一个mysql数据库

因为mysql比较大, 所以,我使用的是docker安装的mysql

下载mysql

docker pull mysql:5.7.15

启动mysql

docker run -p 3306:3306 --name MySQLDocker -v PWD/conf/my.cnf:/etc/mysql/conf.d/my.cnf -vPWD/logs:/var/log/mysql -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.15

2. 创建一个nacos_config的数据库

在这里插入图片描述

3. 初始化nacos_config表结构

在这里找到配置文件: ${nacosHome}/conf/nacos-mysql.

4. 修改application.properties配置文件

在这里插入图片描述

然后重新启动.

在执行上面的写配置

数据库里生成了一条配置信息:


在这里插入图片描述

三. nacos配置

1. 在控制台添加配置

Data ID: nacos-simple-demo.yaml
Group: DEFAULT_GROUP
配置格式: YAML
配置内容: 
common
  config: something

将以上信息在控制台配置好了


在这里插入图片描述

以上就是在nacos服务端建好了配置信息

2. 模拟nacos客户端--获取nacos服务端配置

public class DemoTest {

    public static void main(String[] args) throws NacosException {
        String dataId = "test.demo.yml";
        String group = "DEFAULT_GROUP";
        String serverAddr = "localhost:8848";

        Properties properties = new Properties();
        properties.setProperty("serverAddr", serverAddr);
        // 和nacos服务建立连接
        ConfigService configService = NacosFactory.createConfigService(properties);
        String config = configService.getConfig(dataId, group, 10);
        System.out.println(config);

    }
}

ok, 就可以获取nacos的配置信息了

四. nacos配置管理的模型

对于nacos配置管理, 通过namespace, group, dataId能够定位到一个配置集.

在这里插入图片描述

nacos的配置管理模型包含三部分: namespace, group, service/data Id. 通过配置管理模型, 我们可以定位到所需要的配置文件

其中service/data Id中. server是服务发现, dataId是配置管理.

1. 配置集(DataId)

配置集就是上图的DataId

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

2. 配置项

配置集中包含的一个个配置内容, 就是配置项. 他代表具体的可配置的参数. 通常以key=value的形式存在.

3. 配置分组(Group)

配置分组就是上图中的Group. 配置分组是对配置集进行分组. 通过一个有意义的字符串(如: buy, trade)来表示. 不同的配置分组下可以有相同的配置集(Data ID). 当您在nacos上创建一个配置的时候, 如果未填写配置分组的名称, 则采用默认名称DEFAULT_GROUP.

配置分组的常见场景有: 可用于区分不同的项目或应用. 例如: 学生管理系统的配置集可以定义一个group为:STUDENT_GROUP.

4 命名空间(Namespace)

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

最佳实践
通常我们可以这样定义namespace, group, dataid

  1. Namespace: 代表不同的环境, 如: 开发、测试, 生产等

  2. Group: 可以代表某个项目, 如XX医疗项目, XX电商项目

  3. DataId: 每个项目下往往有若干个工程, 每个配置集(DataId)是一个工程的主配置文件

在这里插入图片描述

结合已有的项目, 进行分析

五. 命名空间的管理

我们先来回顾一下上面的客户端实现. 在上面的客户端实现中,我们是没有定义命名空间的. 那么他会采用默认的命名空间public.


在这里插入图片描述

1. namespace的隔离设计

  • 按照环境来设计namespace: 开发, 测试, 生产
      
    这样不同的环境的配置是相互隔离开的, 互不影响


    在这里插入图片描述
  • 还可以按照多用户的方式来设计. 比如, 张三, 李四,王五, 他们看到的自己的内容是不一样的.

2. 命名空间的管理

创建命名空间


在这里插入图片描述

界面操作比较简单,不都说了

下面我创建了4个命名空间. 其中public和dev都有一个Data Id叫做test.demo.yml. 我要通过程序代码获取dev下的test.demo.yml配置文件.


在这里插入图片描述

模拟客户端获取nacos的命名空间为dev下的配置信息:

package com.lxl.org;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;

import java.util.Properties;

public class DemoTest {

    public static void main(String[] args) throws NacosException, InterruptedException {
        String dataId = "test.demo.yml";
        // 注意: 这里填的是命名空间的id
        String namespace = "dev";
        String group = "DEFAULT_GROUP";
        String serverAddr = "localhost:8848";

        Properties properties = new Properties();
        properties.setProperty("serverAddr", serverAddr);
        properties.setProperty("namespace", namespace);
        // 和nacos服务建立连接
        ConfigService configService = NacosFactory.createConfigService(properties);
        String config = configService.getConfig(dataId, group, 10);
        System.out.println(config);


        Thread.sleep(1000);
    }
}

需要指定要获取的配置是哪个命名空间下面的.

3. 查看历史版本

历史版本这里就说一点, 那就是可以回滚. 点击回滚, 就回滚到了某个版本的配置

4. 监听查询

在这里插入图片描述

想要监听开发环境下, 某个配置文件. 则课一下监听查询中查看哪些配置文件被监听了.

比如: 我们写一个demo, 监听dev下的test.demo.yaml配置文件

public static void main(String[] args) throws NacosException, InterruptedException {
       String dataId = "test.demo.yml";
       // 注意: 这里填的是命名空间的id
       String namespace = "a127e7f7-e37e-48fb-9968-cca7ef7c9f26";
       String group = "DEFAULT_GROUP";
       String serverAddr = "localhost:8848";

       Properties properties = new Properties();
       properties.setProperty("serverAddr", serverAddr);
       properties.setProperty("namespace", namespace);
       // 和nacos服务建立连接
       ConfigService configService = NacosFactory.createConfigService(properties);
       String config = configService.getConfig(dataId, group, 10);
       System.out.println(config);


       configService.addListener(dataId, group, new Listener() {
           @Override
           public Executor getExecutor() {
               return null;
           }

           @Override
           public void receiveConfigInfo(String s) {
               // 接收监听到的返回的配置信息
               System.out.println(s);
           }
       });

       Thread.sleep(1000000);
   }

写一个监听程序, 不停的进行监听. 一旦有配置发生变化, 立刻就可以通知过来.

5. 登录管理

nacos支持简单的登录功能, 默认的用户名/密码是: nacos/nacos.

修改默认用户名和密码的方法:

通过看源码可以知道, nacos用户加密使用的是BCrypt加密的方式. 因此,我们可以模拟一个BCrypt方法进行修改密码

  • 在项目中引入BCrypt 的jar包
 <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>
 

然后写一个修改密码的方法

package com.lxl.org;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class PasswordHandler {
    public static void main(String[] args) {
        String encode = new BCryptPasswordEncoder().encode("123");
        System.out.println(encode);
    }
}

输出结果替换数据库中的密码即可

$2a$10$LW/6RKgceuALErDPcU8THOT5V1Ajc98jgo6N38oOX0Tvmce39hP4a

新加用户, 需要设置用户的用户名和角色

insert into users(username, password, enabled) VALUES ("lxl", "$2a$10$LW/6RKgceuALErDPcU8THOT5V1Ajc98jgo6N38oOX0Tvmce39hP4a", 1);
insert into roles(username, role) VALUES ('lxl', 'ROLE_ADMIN')

也可以在控制台修改

六. Nacos配置管理应用于分布式系统

下图展示了nacos集中管理多个配置服务的流程


在这里插入图片描述
  1. 用户通过nacos 服务的控制台对配置文件进行集中管理

  2. 各服务统一从nacos中获取各自的配置, 并监听配置的变化.


1. 模拟两个微服务请求一个注册中心的场景.

1. 在dev环境下, 新建两个配置文件. server1, server2

在这里插入图片描述

2. 创建一个简单的微服务架构. 采用spring cloud微服务架构.
创建一个parent工程, 引入公共的配置. 在创建两个微服务server1, server2
创建一个parent maven工程, 引入maven包

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

创建一个service1. 然后添加nacos的maven管理. 在添加bootstrap.yml配置文件, 最后增加启动类

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

配置文件bootstrap.yml. 这里需要注意的是默认查找的data Id是应用面+扩展名

server:
  port: 56010

spring:
  application:
    name: service1
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yaml
        namespace: dev
        group: TEST_GROUP
        # 查找默认的data Id --> 应用名 + 文件扩展名-->service1.yaml

最后增加启动类, 里面直接定义了一个controller, 获取配置信息

package com.lxl.www.service1;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class BootStrapApplication {
    public static void main(String[] args) {
        SpringApplication.run(BootStrapApplication.class, args);
    }

    /**
     *  采用注解的方式读取nacos配置信息
     */
    @Value("${common.config}")
    private String config1;


    /**
     * 定义一个controller
     */
    @GetMapping(value = "/config")
    public String getNacosConfig() {
        return config1;
    }
}

service2也是如此.

注意: nacos发布的时候, 要打开日志文件, 看看是否发布成功. 如果报异常, 可能发布不成功. 项目获取配置文件失败
在这里插入图片描述

这里客户端使用的是阿里提供的nacos客户端: spring-cloud-starter-alibaba-nacos-config

存在的问题:

当使用spring的注解@Value的时候, 我们发现, 在配置中心修改了配置文件的内容, 但是通过注解读取出来的内容没变. 这是什么愿意闹呢?其实, 配置文件修改了内容以后, 他是通知了服务端的, 之所以没改, 是因为@Value属性的原因, 他应该是有缓存了. 那么如果想动态获取修改后的配置文件, 有两种方式:

方式一: 使用properties.

获取配置的方式, 修改如下:

   @Autowired
    private ConfigurableApplicationContext applicationContext;

    /**
     * 定义一个controller
     */
    @GetMapping(value = "/config")
    public String getNacosConfig() {
        return applicationContext.getEnvironment().getProperty("common.config");
    }

方式二: @NacosValue

注意事项:

  • nacos的配置信息要写在bootstrap.yml中. 让其配置信息优先加载. (bootstrap.yml加载的时间要比application.yml早)

2. 扩展DataId, 多配置处理

如果有多个配置文件, 我们可以使用扩展配置的方式, 添加多个配置文件

扩展配置id, 第一个扩展的配置id
ext-config[0]:
    data-id: ext-config-common01.yml

ext-config[1]:
    data-id: ext-config-common02.yml
    group: GLOBAL_GROUP

ext-config[2]:
    data-id: ext-config-common03.yml
    group: REFRESH_GROUP
    refresh: true #配置修改, 是否刷新          

第一个配置, 只有一个data-id. 没有group, 采用默认的DEFAULT_GROUP.

第二个扩展配置. 定义了一个GLOBAL_GROUP. 全局配置

第三个扩展配置: 定义为一个自动刷新的GROUP, 并设置自动刷新属性为true
接下来我们在控制台添加这三个文件


在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

修改接口获取配置信息

    /**
     * 定义一个controller
     */
    @GetMapping(value = "/config")
    public String getNacosConfig() {
        String p1 = applicationContext.getEnvironment().getProperty("common.config");
        String p2 = applicationContext.getEnvironment().getProperty("common.ext1");
        String p3 = applicationContext.getEnvironment().getProperty("common.ext2");
        String p4 = applicationContext.getEnvironment().getProperty("common.ext3");
        return p1 + "+" + p2 + "+" + p3 + "+" + p4;
    }

我们可以看到打印出来的效果


在这里插入图片描述

这时, 在控制台修改配置文件, 我们发现common.config会改变. common.ext3会改变. 其他两个不会自动更新

总结: 默认配置是可以自动刷新的. 在扩展配置中, 只有增加了属性refresh:true, 才会自动刷新

3. 共享Data Id

我们可以设置共享data id, 设置方法如下:

在这里插入图片描述

设置共享的data id. 我们设置了三个文件. 启动项目, 运行结果如下

在这里插入图片描述

我们发现, 有两个是null. 为什么是null呢? 因为使用这种方式配置, 只能第一个文件生效, 因此, 如果想要配置多个扩展文件, 还要使用扩展dataId的方式.

4. 配置Data Id的优先级

目前有三种设置Data Id的方式

  • 默认的data id. 项目名+扩展名的方式.
  • 使用ext-config[0] 设置扩展配置
  • 使用shared-dataids: 设置共享配置.

那么, 他们三个的优先级是什么样的呢?

默认配置 > ext-config > shared-dataids
如果有多个ext-config扩展配置, 谁的优先级高呢? n的个数越大, 优先级越高.....

ext-config[n] > ext-config[2] > ext-config[1] > ext-config[0]

5. 关闭Nacos配置

如果不想要使用nacos配置了, 那么可以使之enable属性为false

七. Nacos集群部署

通常我们在生成环境不可能只有一台nacos. 为了保证高可用性, 我们会配置多台nacos.

要求: 配置3台或以上nacos服务

下面我们来模拟三台nacos服务集群

第一步: 解压三个nacos服务


在这里插入图片描述

第二步: 修改配置文件

  1. 修改端口号. 分别设置为8848, 8849, 8850
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2. 添加本地服务的ip地址

给三个服务都增加下面这个配置内容: 设置本机的ip地址

nacos.inetutils.ip-address=127.0.0.1

3. 设置三个nacos的集群关系

修改cluster.conf.example文件为cluster.conf

并在里面添加如下内容


在这里插入图片描述

第四步: 启动三台服务器. 以集群的模式启动
./start.sh -m cluster
然后, 在控制他查看集群, 有一台主, 两台从

在这里插入图片描述

第五步 在项目中配置nacos集群

在这里插入图片描述

注意: 多个配置之间不能带空格.

重启项目. 访问接口返回内容


在这里插入图片描述

这里面, 我们可以停掉任何一台nacos服务. 只要还有一个能运行, 服务就可以访问通

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容