阿里Nacos配置中心简单使用
简介
Nacos 是 Dynamic Naming and Configuration Service 的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos 致力于帮助你发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助你快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助你更敏捷和容易地构建、交付和管理微服务平台。
运行前准备
数据库初始化
将 nacos-mysql.sql 在自己的数据库初始化
本地jar运行
下载及运行
下载地址
包含源码和打包好的压缩包,运行nacos-server中的 start.cmd
需要配置 JAVA_HOME
环境变量,实际运行的是target下的server.jar,最终运行的是nacos-console中的Nacos类。
运行遇到的问题
问题1
"nacos is starting with cluster"
Error occurred during initialization of VM
Could not reserve enough space for 2097152KB object heap
内存不足,需要2G,可以修改start.cmd中的启动参数
set "NACOS_JVM_OPTS=-server -Xms1g -Xmx1g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=%BASE_DIR%\logs\java_heapdump.hprof -XX:-UseLargePages"
将Xms2g改为Xms1g。
问题2
ErrMsg:jmenv.tbsite.net
默认是集群运行,需要单机运行
start.cmd -m standalone
问题3
UnsupportedOperationException:Cannot determin JNI Library name for ARCH='x86' OS='windows 10' name='rocksdb'
本地的jdk版本有问题,使用的是32位的版本,需要使用64位的。
源码运行
修改数据库连接参数
nacos-console下的application.properties文件
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://xxx:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=10000&autoReconnect=true
db.user=xxx
db.password=xxx
添加启动参数 -Dnacos.standalone=true,运行nacos-console子项目下的Nacos启动类。
nacos默认使用内置数据库apache的derby数据库。如果配置了spring.datasource.platform=mysql,就使用外部数据库mysql。具体逻辑判断在 DynamicDataSource 和 PropertyUtil 类中。NacosDefaultPropertySourceEnvironmentPostProcessor 会查找META-INF\nacos-default.properties文件,其中包含很多默认属性,如服务器端口server.port=8848,如果设置了自定义配置,就会覆盖默认的。
源码编译错误
Error:(21, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在
IDEA中通过protobuf插件编译一下
通过docker运行
下载镜像
docker pull nacos/nacos-server:2.0.2
运行
docker run -d --name nacos-server \
-e MODE=standalone \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=ip \
-e MYSQL_SERVICE_PORT=port \
-e MYSQL_SERVICE_DB_NAME=nacos \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=pwd \
-e MYSQL_DATABASE_NUM=1 \
-e JVM_XMS=128m \
-e JVM_XMX=128m \
-p 8848:8848 nacos/nacos-server:2.0.2
启动参数可以参考官方文档
后台操作
开启服务器防火墙的 8848 端口限制,浏览器访问 http://ip:8848/nacos
,默认账号密码 nacos/nacos。
给客户端添加配置
- namespace: 相当于环境,可以为dev,test,pro等
- dataId: 相当于项目,例如myadmin
- group: 相当于项目的分组,基本不用
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
bootstrap.yml
spring:
application:
name: demo1
cloud:
nacos:
config:
server-addr: http://ip:8848
namespace: d8b0df04-aa58-4a5b-b582-7d133b9e8b2c #命名空间ID
username: nacos
password: nacos
extension-configs:
- data-id: server.yaml
refresh: true
- data-id: redis.yaml
refresh: true
开启客户端鉴权
nacos-console的application.properties中
nacos.core.auth.enabled=true
先创建用户,再给用户创建角色,再给角色绑定权限(命名空间)
原理分析
客户端读取配置
- NacosConfigBootstrapConfiguration注入NacosPropertySourceLocator类(具体读取配置),是为了兼容spring-cloud的读取配置中心的规则。
- NacosPropertySourceLocator类内部通过NacosConfigService类来发送请求读取配置
最终调用的接口为 http://localhost:8848/nacos/v1/cs/configs
配置自动刷新
@Data
@Component
@RefreshScope
public class UserProperties {
@Value("${myuser.name}")
private String name;
}
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private UserProperties userProperties;
@GetMapping("/testRefreshQuery")
@ApiOperation("测试刷新对象查询")
public String testRefreshQuery() {
return userProperties.getName();
}
}
主要原理就是客户端定时通过长轮训去服务端拉取数据
- NacosContextRefresher监听ApplicationReadyEvent事件,注册Nacos配置改变的事件监听器(AbstractSharedListener的匿名子类)
- NacosConfigService中的ClientWorker会开启一个定时任务
- LongPollingRunnable为具体的长轮训任务,具体为checkUpdateDataIds()方法
- 请求头Long-Pulling-Timeout设置超时时间30秒。
- 获取到配置改变之后就会通知监听器
- 监听器发布RefreshEvent时间
- RefreshEventListener处理此事件,调用ContextRefresher的refresh()方法。
- 之后就是SpringCloud的自动刷新机制了(@RefreshScope注解)。