Nacos-配置管理
Posted 杀手不太冷!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nacos-配置管理相关的知识,希望对你有一定的参考价值。
Nacos-配置管理
1.什么是配置中心
1.1什么是配置
应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数据库链接参数,启动参数等。
配置主要有以下几个特点:
a.配置是独立于程序的只读变量
配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置。
b.配置伴随着应用的整个生命周期
配置贯穿于应用 的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。比如:启动时需要读取服务的端口号,系统在运行过程中需要读取定时策略执行定时任务等。
c.配置可以用多种加载方式
常见的有程序内部hard code硬编码,配置文件,环境变量,启动参数,基于数据库等
d.配置需要治理
同一份程序在不同的环境(开发,测试,生产),不同的集群(如不同的数据中心)经常需要有不同的配置,所以需要有完善的环境,集群配置管理。
1.2什么是配置中心
在微服务架构中,当系统从一个单体应用,被拆分成分布式系统上一个个服务节点后,配置文件也必须跟着迁移(分割),这样配置就分散了,不仅如此,分散中还包含着冗余,如下图:
下图显示了配置中心的功能,配置中心将配置从各应用中剥离出来,对配置进行统一管理,应用自身不需要自己去管理配置
配置中心是一个独立部署的服务,它可能在一个独立的服务器上。
2.Nacos简介
2.1主流配置中心对比
目前市面上用的比较多的配置中心有:Spring Cloud Config,Apollo,Nacos和Disconf等。
由于Disconf不再维护,下面主要对比一下Spring Cloud Config,Apollo和Nacos
对比项目 | Spring Cloud Config | Apollo | Nacos |
---|---|---|---|
配置实时推送 | 支持(Spring Cloud Bus) | 支持(HTTP长轮询1s内) | 支持(HTTP长轮询1s内) |
版本管理 | 支持(Git) | 支持 | 支持 |
配置回滚 | 支持(Git) | 支持 | 支持 |
灰度发布 | 支持 | 支持 | 不支持 |
权限管理 | 支持(依赖Git) | 支持 | 不支持 |
多集群 | 支持 | 支持 | 支持 |
多环境 | 支持 | 支持 | 支持 |
2.2Nacos简介
Nacos是阿里的一个开源产品,它是针对微服务架构中的服务发现,配置管理,服务治理的综合型解决方案。
官方介绍是这样的:Nacos致力于帮助您发现,配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您实现动态服务发现,服务配置管理,服务及流量管理。Nacos帮助您更敏捷和容易地构建,交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构的服务基础设施。
官方地址:https://nacos.io
2.3Nacos特性
Nacos主要提供了以下四大功能:
1.服务发现与服务健康检查
Nacos使服务更容易注册,并通过DNS或HTTP接口发现其他服务,Nacos还提供服务的实时健康检查,以防止向不健康的主机或服务实例发送请求。
2.动态配置管理
动态配置服务允许您在所有环境中以集中和动态的方式管理所有服务的配置。Nacos消除了在更新配置时重新部署应用程序,这使配置的更改更加高效和灵活。
3.动态DNS服务
Nacos提供基于DNS协议的服务发现能力,旨在支持异构语言的服务发现,支持将注册在Nacos上的服务以域名的方式暴露端点,让三方应用方便的查询及发现。
4.服务和元数据管理
Nacos能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述,生命周期,服务的静态依赖分析,服务的健康状态,服务的流量管理,路由及安全策略。
3.Nacos快速入门
安装Nacos Server
1.从https://github.com/alibaba/nacos/releases下载gz包,如下图:
2.解压缩nacos-server-2.0.2.tar.gz得到Nacos文件夹
启动Nacos Server
3.启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
nacos-server启动之后的默认端口号是8848。
在浏览器中访问nacos
向nacos中发布配置
4.OPEN API配置管理测试
启动nacos成功之后,可以通过nacos提供的http api验证nacos服务运行是否正常。
下边我们通过curl工具来测试nacos的open api:
curl是开发中常用的命令行工具,可以用作HTTP协议测试,可以简单的把curl理解成:命令行的浏览器,也即是虽然是在命令行执行的命令,但是它的作用其实就像把url运行在浏览器的效果是一样的。
本教程下载curl的mac版本:下载地址:https://curl.haxx.se/mac
下载完成后,解压,如下图:
往nacos-server上发布配置,命令:curl -X POST “http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld”,其实在命令行终端执行完此命令之后,也就相当于是在浏览器中执行了http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld
mac电脑解压完curl.tar.gz之后,可以直接在终端使用curl命令,mac电脑不需要给curl配置环境变量,解压之后可以直接使用。
在终端发布配置如下图:
在nacos中查看发布的配置,如下图:
从nacos中获取配置
向nacos发布配置成功,就可以通过客户端从nacos获取配置信息,执行下边的命令:
curl -X GET “http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test”
通过测试发现,可以从nacos获取前边发布的配置:HelloWorld如下图:
关闭nacos服务器
执行命令sh shutdown.sh即可,如下图:
外部mysql数据库支持
下载mysql服务器
下载mysql,如下图:
mysql服务器存放的默认路径如下图:
使用Sequel Pro数据库管理工具客户端访问本地mysql服务器
如下图:
若想使用外部的mysql存储nacos数据,则需要进行以下步骤
单机模式时nacos默认使用嵌入式数据库实现数据的存储,若想使用外部mysql存储nacos数据,需要进行以下步骤:
1.初始化mysql数据库,新建数据库nacos_config,数据库初始化文件:nacos/conf/nacos-mysql.sql,如下图:
在本地mysql服务器中创建一个nacos-mysql数据库,然后把nacos-mysql.sql导入到这个数据库里面,如下图:
上面的数据库的名字是nacos_config而不是nacos-mysql已经改过来了。
2.修改nacos/conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url,用户名和密码
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?
characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root
测试nacos是否已经与mysql成功连接了,如下图:
关闭nacos然后重启nacos,进入nacos/conf/bin目录,然后执行sh shutdown.sh命令,接着执行sh startup.sh -m standalone命令。
然后在nacos里面新建命名空间,新建的命名空间的信息会存储到mysql数据库nacos_config中的tenant_info表中,如下图:
然后去nacos_config数据库中的表tenant_info中查看有没有增加信息,如下图:
到这里,nacos中就成功引入外部mysql数据库支持了。
4.通过idea代码获取nacos的public环境中的某个配置集
发布配置
首先在nacos发布配置。浏览器访问http://127.0.0.1:8848/nacos,打开nacos控制台,并点击菜单配置管理->配置列表:
在Nacos添加如下的配置:
Data ID: nacos-simple-demo.yaml
Group: DEFAULT_GROUP
配置格式: YAML
配置内容: common:
config: something
如下图:
注意:上图中的Data ID的值的扩展名是yaml,这个扩展名和下面的配置内容的配置格式要保持一致。
在public环境中发布配置成功之后,如下图:
创建一个maven项目工程,如下图:
添加依赖,如下图:
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.1.3</version>
</dependency>
写一个可以从nacos配置中心获取配置的代码,如下图:
4.Nacos配置管理基础应用
4.1Nacos配置管理模型
对于Nacos配置管理,通过Namespace、group、Data ID能够定位到一个配置集。
配置集(Data ID)
在系统中,一个配置文件通常就是一个配置集,一个配置集可以包含了系统的各种配置信息,例如,一个配置集俄能包含了数据源,线程池,日志级别等配置项。每个配置集都可以定义一个有意义的名称,就是配置集的ID即Data ID。
配置项
配置集中包含的一个个配置内容就是配置项。它代表一个具体的可配置的参数与其值域,通常以key=value的形式存在。例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|REEOR)就是一个配置项
配置分组(Group)
配置分组是对配置集进行分组,通过一饿有意义的字符串(如Buy或Trade)来表示,不同的配置分组下可以有相同的配置集(Data ID)。当您在Nacos上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用DEFAULT_GROUP。配置分组的常见场景:可用于区分不同的项目或应用,例如:学生管理系统的配置集可以定义一个group为:STUDENT-GROUP.
命名空间(Namespace)
命名空间(namespace)可用于进行不同环境的配置隔离。例如可以隔离开发环境,测试环境和生产环境,因为它们的配置可能各不相同,或者是隔离不同的用户,不同的开发人员使用同一个nacos管理各自的配置,可通过namespace隔离。不同的命名空间下,可以存在相同名称的配置分组(Group)或配置集。
最佳实践
Nacos抽象定义了Namespace、Group、Data ID的概念,具体这几个概念代表什么,取决于我们把它们看成什么,这里推荐给大家一种用法,如下图:
Namespace:代表不同环境,如开发、测试、生产环境。
Group:代表某项目,如XX医疗项目、XX电商项目
DataId:每个项目下往往有若干个工程,每个配置集(DataId)是一个工程的主配置文件
4.2命名空间管理
4.2.1namespace隔离设计
namespace 的设计是 nacos 基于此做多环境以及多租户(多个用户共同使用nacos)数据(配置和服务)隔离的。
从一个租户(用户)的角度来看,如果有多套不同的环境,那么这个时候可以根据指定的环境来创建不同的namespce,以此来实现多环境的隔离。例如,你可能有开发,测试和生产三个不同的环境,那么使用一套nacos 集群可以分别建以下三个不同的 namespace。如下图所示:
从多个租户(用户)的角度来看,每个租户(用户)可能会有自己的 namespace,每个租户(用户)的配置数据以及注册的服务数据都会归属到自己的 namespace 下,以此来实现多租户间的数据隔离。例如超级管理员分配了三个租户,分别为张三、李四和王五。分配好了之后,各租户用自己的账户名和密码登录后,创建自己的命名空间。如下图所示:
注意: 在此教程编写之时,nacos多租户(用户)功能还在规划中。
4.2.2命名空间的管理
前面已经介绍过,命名空间(Namespace)是用于隔离多个环境的(如开发、测试、生产),而每个应用在不同环境的同一个配置(如数据库数据源)的值是不一样的。因此,我们应针对企业项目实际研发流程、环境进行规划。
如某软件公司拥有开发、测试、生产三套环境,那么我们应该针对这三个环境分别建立三个namespace。
建立好所有namespace后,在配置管理与服务管理模块下所有页面,都会包含用于切换namespace(环境)的tab按钮,如下图:
新建命名空间,如下图:
注意上图中有一个命名空间id,当我们想要拿到namespace的值的时候,要拿命名空间id的值,不要拿命名空间名称这个值。
配置好命名空间之后,可以在配置列表这个地方切换命名空间,如下图:
指定namespace的值,如果不指定的话默认是public环境的namespace
从dev环境中获取dataId为"nacos-simple-demo.yaml",group为"DEFAULT_GROUP"的配置集,因为现在是从dev环境中获取,而不是从public环境中获取,因此必须要指定dev的namespace命名空间,所以要更改一下idea中获取配置的代码,首先来看一下dev环境中的配置信息,如下图:
4.3功能操作
克隆配置集
导入导出环境中的所有配置集
回滚配置集
在idea中监听配置集
在原来代码的基础上,加上一些代码,如下图:
然后去更改dev环境中的配置集,那么更改后的信息就会在idea的控制台中显示出来,如下图:
4.4登录管理
Nacos当前版本支持简单的登录功能,默认用户名/密码为:nacos/nacos
修改默认用户名/密码方法
1.生成加密密码
在入门程序中加入如下依赖,如下图:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
编写PasswordEncoderUtil类,生成加密后的密码,采用BCrypt加密方法在每次生成密码时会加随机盐,所以生成密码每次可能不一样。
public class PasswordEncoderUtil {
public static void main(String[] args) {
String encode = new BCryptPasswordEncoder().encode("456");
System.out.println(encode);
}
}
然后往数据库的users表中插入一条数据,插入语句如下:
INSERT INTO users (username, password, enabled) VALUES ('nacos2',
'$2a$10$yDCiDNExUEf6Av15Ab9jxu9pH4ORwzt8RuPFevFNcve9p/NxL275W', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos2', 'ROLE_ADMIN');
当前数据库的users表中的内容如下图:
然后把用户名是nacos1,密码是加密后的456的字符串的这句代码插入进来,如下图:
登录测试,如下图:
但是我的不能登录,不知道为什么,和博主的一样,博主可以登录,但是我的却不能登录。可以登录了,bug找到了如下图:
通过修改配置文件,去掉nacos的登录验证功能,如下图:
但是这个我测试的仍然需要登录验证,也不知道为什么,先记住nacos的登录管理的功能,bug先放着。
5.Nacos配置管理应用于分布式系统
5.1从单体架构到微服务
5.1.1单体架构
Web应用程序发展的早期,大部分web工程师将所有的功能模块打包到一起并放在一个web容器中运行,所有功能
模块使用同一个数据库,同时,它还提供API或者UI访问的web模块等。
尽管也是模块化逻辑,但是最终它还是会打包并部署为单体式应用,这种将所有功能都部署在一个web容器中运行
的系统就叫做单体架构(也叫:巨石型应用)。
单体架构有很多好处:
-
开发效率高:模块之间交互采用本地方法调用,并节省微服务之间的交互讨论时间与开发成本。
-
容易测试:IDE都是为开发单个应用设计的、容易测试——在本地就可以启动完整的系统。
-
容易部署:运维成本小,直接打包为一个完整的包,拷贝到web容器的某个目录下即可运行。
但是,上述的好处是有条件的,它适用于小型简单应用,对于大规模的复杂应用,就会展现出来以下的不足:
-
复杂性逐渐变高,可维护性逐渐变差 :所有业务模块部署在一起,复杂度越来越高,修改时牵一发动全身。
-
版本迭代速度逐渐变慢:修改一个地方就要将整个应用全部编译、部署、启动时间过长、回归测试周期过长。
-
阻碍技术创新:若更新技术框架,除非你愿意将系统全部重写,无法实现部分技术更新。
-
无法按需伸缩:通过冗余部署完整应用的方式来实现水平扩展,无法针对某业务按需伸缩。
5.1.2微服务架构
许多大型公司,通过采用微服务架构解决了上述问题。其思路不是开发一个巨大的单体式的应用,而是将应用分解为小的、互相连接的微服务。
一个微服务一般完成某个特定的功能,比如订单服务、用户服务等等。每一个微服务都是完整应用,都有自己的业务逻辑和数据库。一些微服务还会发布API给其它微服务和应用客户端使用。
比如,根据前面描述系统可能的分解如下:
每一个业务模块都使用独立的服务完成,这种微服务架构模式也影响了应用和数据库之间的关系,不像传统多个业务模块共享一个数据库,微服务架构每个服务都有自己的数据库。
微服务架构的好处:
- 分而治之,职责单一;易于开发、理解和维护、方便团队的拆分和管理
- 可伸缩;能够单独的对指定的服务进行伸缩
- 局部容易修改,容易替换,容易部署,有利于持续集成和快速迭代
- 不会受限于任何技术栈
5.2分布式应用配置管理以及微服务创建
下图展示了如何通过Nacos集中管理多个服务的配置:
用户通过 Nacos Server的控制台集中对多个服务的配置进行管理。
各服务统一从 Nacos Server中获取各自的配置,并监听配置的变化。
发布配置
首先在nacos中发布配置,我们规划了两个服务service1,service2,并且想对这两个服务的配置进行集中维护。
浏览器访问http://127.0.0.1:8848/nacos,打开nacos控制台,点击菜单。配置管理->配置列表:
在Nacos中添加如下的配置:
创建父工程
因为是微服务,所以会有很多个工程,但是这些工程可能会依赖同一些依赖坐标,因此为了规范依赖的版本,这里创建父工程,指定依赖的版本,然后让所有的微服务工程都依赖这个父工程,创建父工程的流程如下图:
然后在父工程的pom.xml依赖中,引入下面的依赖,如下:
<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,service2配置
本小节,我们将演示如何使用Spring Cloud Alibaba tacos Config在Spring Cloud应用中集成Nacos,通过Spring cloud原声方式快捷的获取配置内容。
Spring Cloud是什么:
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册,配置中心,消息总线,负载均衡,断路器,数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟,经得起实际考验的服务框架组合起来,集成最多的组件要属Netflix公司,通过Spring boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂,易部署和易维护的分布式系统开发工具包。
Spring Cloud Alibaba Nacos Config是什么:
Spring Cloud Alibaba Nacos Discovery是Spring Cloud Alibaba的子项目,而Spring Cloud Alibaba是阿里巴巴公司提供的开源的基于Spring Cloud的微服务套件合集,它致力于提供微服务开发的一站式解决方案,可以理解为Spring Cloud是一套微服务开发的标准,Spring Cloud alibaba与Spring Cloud Netflix是实现。使用Spring Cloud Alibaba方案,开发者只需要添加一些注解和少量配置,就可以将Spring Cloud应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。
由于Nacos是阿里的中间件,因此,若开发Spring Cloud微服务应用,使用Spring Cloud Alibaba Nacos Config来集成nacos的配置管理功能是比较明智的选择。
(1)新建项目service1
首先新增一个名为service1的工程,并添加group ID为com.alibaba.cloud和artifact ID为spring-cloud-starter-alibaba-nacos-config的starter。
添加依赖,如下:
<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>
同样的方法,创建一个service2工程,并往配置文件中添加和service1工程相同的依赖。
(2)bootstrap.yml配置
一般来说,spring boot的配置将在application.yml(也可以是application.properties)文件中编写,由于使用外部配置中心,必须将原先的application.yml重命名为bootstrap.yml,bootstrap.yml如下所示:
Spring.cloud.nacos.config.server-addr指定了nacos Server的网络地址和端口号。
bootstrap.yml中的内容如下:
server: port: 56010 #启动端口 命令行注入spring: application: name: service1 cloud: nacos: config: server-addr: 127.0.0.1:8848 #配置中心地址 file-extension: yaml namespace: 672f4ed9-972e-49bb-af3a-38bbd42bff41 #开发环境 group: TEST_GROUP #测试组
以上配置文件说明该应用将从地址为127.0.0.1:8848配置中心获取配置,通过一下信息定位到配置集:
namespace: 672f4ed9-972e-49bb-af3a-38bbd42bff41 #开发环境group: TEST_GROUP #测试组Data Id: service1.yaml#如果没有指定spring.cloud.nacos.config.group配置,则默认为DEFULT_GROUP
(3)启动配置客户端
新增Spring Boot启动类,并增加获取配置的web访问端点/configs,通过标准的Spring@value方式。如下图
service2和service1的配置基本上一致,注意一点,就是服务器的启动端口一定要不一样。
微服务读取配置信息
通过Value注解读取到nacos配置中心中的配置集中的信息,如下图:
启动成功之后在浏览器中访问接口,如下图:
但是通过value注解获取到的配置集,会存在一个问题,就是,加入在nacos配置中心里更改了配置集的信息,那么是不能同步到idea的service1工程中的,也就是在浏览器里面访问127.0.0.1:56010/configs接口,输出内容仍然是原来的内容。怎么实现动态更新呢?请往下看。
支持配置的动态更新
基于上面快速上手的例子,若想要实现配置的动态更新,只需要进行如下改造:
//注入配置文件上下文 @Autowired private ConfigurableApplicationContext applicationContext; @GetMapping(value = "/configs") public String getConfigs(){ return applicationContext.getEnvironment().getProperty("common.name"); }
接着去浏览器中测试接口,如下图:
5.3自定义扩展dataid
自定义扩展dataid可以实现一个微服务对应多个配置集,不再仅仅局限于一个微服务对应着一个配置集。比如说可以把公共数据库的配置文件,放到一个独立的配置集里面,然后让每个微服务都加载这个配置集。
在dev环境中新增配置集,如下:
测试如下图:
以上是关于Nacos-配置管理的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud Nacos配置管理 -- 统一配置管理(添加配置微服务配置拉取)