应用程序在启动或运行时需要读取一些配置信息,配置基本上伴随着程序的整个生命周期,如:数据库连接参数、启动参数。
配置主要有以下几个特点:
1)配置是独立程序的只读变量
配置对应程序是只读的,通过配置去改变程序,而不应该通过程序去改变配置。
配置伴随着程序的整个生命周期
配置贯穿于应用的整个生命周期,应用在启动时读取配置进行初始化,在运行时根据配置调整行为。
比如:启动 时需要读取服务的端口号、系统在运行过程中需要读取定时策略执行定时任务等。
2)配置可以有多种加载方式
常见的程序内部hard code、环境变量、配置文件、启动参数、基于数据库等。
3)配置需要治理
同一个程序在不同的环境(开发、生产、测试),不同的集群(如不同的数据中心)经常需要不同的配置文件,所以要有完善的环境、集群配置管理。
在微服务架构中,将一个单体服务拆分成多个节点的分布式系统后,配置文件也就被独立了(分割),配置会分散,并且会造成过多的冗余。
用户发布/修改配置 ->配置中心对服务A(配置客户端)进行配置更新通知 ->服务从配置中心获取最新的配置
Nacos是阿里巴巴的一个开源产品,它是针对微服务架构中的服务发现,配置管理,服务治理的综合解决方案。
官方介绍:
Nacos致力于帮助您发现,配置和管理微服务,Nacos提供了一组简单易用的特性集,帮助您实现动态服务发现、服务配置管理、服务及流量管理。
Nacos帮助您更敏捷和更容易的构建、交付和管理微服务平台,Nacos是构建以“服务”为中心的现代应用架构的服务基础设施。
目前市面上主要的配置中心有:SpringCloud Config、Apollo、Nacos和DisConf等。
DisConf已经不在维护,主要对比SpringCloud Config、Nacos等。
Nacos主要提供以下的四大功能:
1.服务发现与服务健康检查
Nacos使服务更容易注册,并通过DNS或HTTP接口发现其他服务,Nacos还提供服务健康检查,以防止不健康的主机或服务实例发送请求。
2.动态配置管理
动态管理配置允许您在环境中以集中和动态的方式管理所有服务的配置。Nacos消除了在更新配置时,需要重新部署应用程序的缺点,这使配置的更改更加高效灵活。
3.动态DNS服务
Nacos提供DNS协议的服务发现能力,皆在支持异构语言的服务发现,支持将注册Nacos上的服务以域名方式暴露节点,让第三者更加方便查阅和发现。
4.服务和元数据管理
Nacos能让你从微服务平台建设的视角去管理数据中心的所有数据及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略。
Nacos依赖JAVA环境来运行,如果是从代码开始构建并运行Nacos,还需配置Maven环境,请确保是在以下环境中运行:
1)64bit OS,支持 Liunx、Unix、Mac、Windows,推荐使用Liunx、Unix、Mac。
2)64Bit JDK1.8+
3)Maven 3.2.X
地址:https://github.com/alibaba/nacos
Nacos的默认端口是8848,需要保证Nacos端口没有被其他端口占用
进入安装应用程序的bin目录:
Liunx、Unix、Mac启动方式
启动命令(Standalone代表着单机模式运行,非集群模式)
sh startup.sh -m standlone
若使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试下面的运行方式
bash startup.sh -m standalone
Windows启动方式
启动命令
cmd startup.cmd 或者双击 startup.cmd
启动成功 可进入 http://127.0.0.1:8848/nacos nacos控制台登录页面
启动Nacos后,可通过Nacos的HTTP API验证Nacos服务运行是否正常。
下面我们通过curl工具来测试nacos的open api;
curl是我们常用的命令行工具,可用作http协议测试。
进入bin目录,进行测试 ,判断nacos是否正常工作
发布配置
curl -X POST “http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&
content=HelloWorld”
获取配置
curl -X GET “http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test”
发布配置时要填写dataId、groupId、content
获取配置时要填写dataId、groupId来获取content
关闭nacos服务器的方式:
Liunx/unix/mac使用:sh studown.sh
windows使用:cmd-> studown.cmd 或直接关掉黑窗口
单机模式nacos采用默认的嵌入式数据库实现数据的存储,若想用外部的Mysql存储nacos数据,需要进行以下步骤:
1)安装数据库,版本要求:MYSQL 5.6.5+ MYSQL 8以下
2)初始化MYSQL数据库,新建nacos.config,数据库初始化文件在Conf的SQL文件中
3)修改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=3000&authReconnect=true
db.user=root
db.password=root
浏览器访问http://127.0.0.1:8848/nacos,打开nacos控制台,打开菜单 配置管理->配置列表
在Nacos添加如下配置:
Data Id: nacos-simple-demo.yaml
Group: DEFAULT_GROUP
配置格式: YAML
配置内容:common:
config1:something
注:注意选择数据格式,这里使用yaml
第一步:新增配置
坐标:
com.alibaba.nacos
nacos-client
1.0-SNAPSHOT
代码:
//dataId
String dataId = "nacos-simple-demo.yaml";
//Group
String group = "DEFAULT_GROUP";
//nacos 地址
String serverAddr = "http://127.0.0.1:8848/nacos";
Properties properties = new Properties();
properties.put("serverAddr",serverAddr);
ConfigService configService = NacosFactory.createConfigService(propertis);
//获取配置
String content = configService.getConfig(dataId,group,5000);
system.out.println(content);
配置集(Data Id)
在系统中,一个配置文件通常就是一个配置集,一个配置集可以包含多个配置信息。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项,每个配置集都可以定义一个有意义的名字,就是配置集的Id即Data Id。
配置项
配置集中包含了一个个的配置内容就是配置项,它代表一个具体的可配置的参数其域值,通常以key-value形式存储,例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|ERROR)就是一个配置项。
配置分组(group)
配置分组就是对配置集进行分组,通过一个有意义的字符串来表示,不同的配置分组下可以有相同的结果集,若在Nacos创建一个配置但并未设计分组名称,则默认分组名称采用DEFAULT_GROUP。配置分组一般用于区分不同项目不同系统,若:学生信息管理系统 可定义一个STUDENT_GROUP。
命名空间(NameSpace)
命名空间(NameSpace)可以用于不同环境的配置进行隔离。例如隔离开发环境,测试环境,生产环境。因为它们的配置可能各不相同,或是隔离不同的用户,不同的开发人员使用Nacos管理个自的配置,可通过NameSpace隔离,不同命名空间下,可以存在相同名称的配置分组或结果集。
最佳实践
Nacos抽象定义了NameSpace、group、DataId的概念,具体这几个概念代表什么,取决我们把他看做什么,推荐给大家一种用法:
NameSpace:代表不同环境,若开发、测试、生产
Group:代表某项目:XX医疗项目,XX进销存项目
DataId:每个项目下有若干工程,每个配置集是一个工程的主配置文件
获取某配置集的代码
获取配置集需要指定:
1.nacos服务地址必须指定
2.dataId必须指定
3.namespace若是不指定则默认public
4.group,若不指定默认DEFAULT_GROUP
注:创建命名空间后可通过配置管理选项卡,可点击环境随意切换。
代码:
(获取不同命名空间下的配置集)
//定义DataId
String dataId = "";
//定义group
String group = "";
//定义NameSpace
String nameSpace = "";
//定义Nacos地址
String serverAddr = "";
//定义Properties
Properties properties = new Properties();
//赋值
properties .put("namespace",namespace);
properties .put("serverAddr",serverAddr);
//设置参数并获取配置文件内容
ConfigService configService = NacosFactory.ctreateConfigService(properties);
String content= configService .getConfig(dataId,group,400);
system.out.println("原:\n"+content);
配置管理功能点:
1)配置列表
删除配置、克隆配置、导入配置、导出配置、编辑配置
2)历史版本
输入DataId、Group查询历史版本,选择对应时间历史版本进行回滚
3)监听查询
Nacos提供监听查询能力
代码:
//定义DataId
String dataId = "";
//定义group
String group = "";
//定义NameSpace
String nameSpace = "";
//定义Nacos地址
String serverAddr = "";
//定义Properties
Properties properties = new Properties();
//赋值
properties .put("namespace",namespace);
properties .put("serverAddr",serverAddr);
//设置参数并获取配置文件内容
ConfigService configService = NacosFactory.ctreateConfigService(properties);
String content = configService .getConfig(dataId,group,400);
system.out.println("原:\n"+content);
//监听器监听变化
configService.addListener(dataId,group,new Listener(){
public Executor getExecutor(){
return null;
}
//输出修改后的信息
public void receiveConfigInfo(Sting s){
system.out.println(s);
}
});
修改默认用户名密码方法
1.生成加密密码
依赖文件:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactld>
<version>5.1.4.RELEASE</version>
</dependency>
2.生成密码:
System.out.println( new BCryptPassWordEncoder().encode("123"));
3.将生成的密码粘贴到需要保存的用户行密码中
新增用户
insert into users(username,passwod,enabled) values ('nacos','加密的密码',true);
insert into role(username,role) valus ('nacos','ROLE_ADMIN');
nacos免登录
找到conf/application.properties,加入以下内容:
spring.security.enabled=false
management.security=false
security.basic.enabled=false
nacos.security.ignore.urls=/**
即可完成免登录
在早期,项目大多为单体应用,将所有的模块打包到一起放在一个容器进行运行,连接同一个数据库,同时提供API和UI访问模块。即使模块是独立的最终也会打包为一个包进行部署,这就叫单体应用(巨石型应用)。
优点:
①开发效率高 :模块都是本地调用,节省微服务之前的通讯及开发成本。
②容易测试 :在本地就可启动完整的系统。
③容易部署:运维成本小,直接打为一个包就可直接部署运行
缺点:
①复杂性逐渐变高:代码量增加,一发而动全身
②版本迭代速度逐渐变慢:修改一个地方就需要全部重新编译、部署、时间过长。
③无法按需伸缩:无法针对某业务进行按需伸缩。
许多大型公司,通过微服务架构解决单体的缺点,将一个大的应用拆分成小的应用,互相连接的微服务。
每个业务模块都是独立的系统,修改商品服务并不会影响订单服务,微服务也影响了数据库和系统的关系,不仅仅是多个模块共享一个数据库,像微服务框架每个系统都可以有自己的数据库。
优点:
①分而治之、职责单一、易于开发、理解和维护、方便管理。
②可伸缩,单独对指定的服务进行伸缩。
③局部容易修改、替换,易于部署,有利于快速迭代。
④不会受限于任何技术栈
配置方法:
Tomcat
server:
port: 9613
Spring
spring:
application:
# 应用名称
name: bsx-study
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application- s p r i n g . p r o f i l e s . a c t i v e . {spring.profiles.active}. spring.profiles.active.{spring.cloud.nacos.config.file-extension}
· 通过Nacos Server的控制台集中对多个服务的配置进行管理。
· 各服务统一从Nacos获取各自的配置,并监听配置的变化。
可使一个微服务对应多个配置文件,并且可将重复的配置文件(如:数据库连接信息)抽取到一个配置文件中,这样可以避免冗余重复的配置信息。
ext-config[0]:
data-id: nacos-config-advanced.yaml //文件名称及后缀
group: SPRING_CLOUD_EXAMPLE_GROUP //分组名称 默认default_group
refresh: true //动态更新
ALibaba Nacos Config目前提供了三种配置能力从Nacos拉取相关的配置。
A.通过Spring.cloud.nacos.config.shared-dataids支持多个共享DataID的配置
B.通过Spring.cloud.nacos.config.ext-config[n].data-id的方式支持配置多个扩展DataId的配置,多个dataId同时配置时,它的优先关系是根据[n]l来排序的,n越大优先级越高。
C.通过内部相关规则(应用、扩展名)自动生成的配置。.
ABC三种优先级分别是 C>B>A
通过设置Spring.cloud.nacos.config.Enable = false 来完全关闭Spring Cloud Nacos Config
nacos搭建集群需要三个或三个以上的Nacos节点才能构成集群
1)安装三个或三个以上Nacos
将已经解压好的Nacos复制成三份,分别命名为nacos1、nacos2、nacos3
2)配置集群配置文件
在所有nacos目录的conf目录下,有文件cluster.conf.example,将其命名为cluster.conf,并将每行配置成ip:port(三个或三个以上节点)
#ip:port
127.0.0.1:8848
127.0.0.1:8849
127.0.0.1:8850
因为是单机的演示,所以要在conf下的application.properties中server.port,防止端口冲突。
如果服务器有多个IP也要指定具体的IP地址,如:nacos.inetutils.ip-address:127.0.0.1
例如:
server.port = 8850
nacos.inetutils.ip-address = 127.0.0.1
3)集群模式启动
分别执行nacos的bin目录下cmd
startup -m cluster
打开nacos网址:http://127.0.0.1:8848,点击集群管理–节点列表可看到所存在的集群。
spring:
application:
name: XXX
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
准备测试:
1)关掉8848端口的nacos,查看8849端口下的集群状态发现leader被成功选举至8849
2)紧接着重新启动provider,这时马上请求consumer/service出现错误,发现provider与consumer通信已经出现问题,经过短暂时间,方可恢复
通过测试就可以看出已经实现了高可用。