• 2.nacos服务配置中心


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

    1. nacos的角色: nacos是如何工作的? 在集群中扮演什么样的角色?

    2. 修改nacos配置数据库: 我们在控制台配置的信息, 默认是写到nacos的默认数据库中, 不方便管理, 因此我们设置一个自己的数据库, 进行管理操作

    3. 在控制台配置nacos配置

    4. nacos配置管理的模型: 基本概念,namespace, group, data id及其用法

    5. 命名空间的管理, namespace的使用

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

    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 -v $PWD/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下的配置信息:  

    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>

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

    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, 获取配置信息

    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服务. 只要还有一个能运行, 服务就可以访问通 

  • 相关阅读:
    mysql中profile的使用
    6、MySQL索引种类
    MySql事务
    MySQL视图(view)
    MySql数据库命令基本操作
    2、MySQL常见数据库引擎及比较?
    1、列举常见的关系型数据库和非关系型都有那些?
    Python中的顺序表
    双端队列
    手持移动端特殊链接:打电话,发短信,发邮件
  • 原文地址:https://www.cnblogs.com/shanheyongmu/p/15905773.html
Copyright © 2020-2023  润新知