什么是 Nacos
概览
欢迎来到 Nacos 的世界!
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
什么是 Nacos?
服务(Service)是 Nacos 世界的一等公民。Nacos 支持几乎所有主流类型的“服务”的发现、配置和管理:
Nacos 的关键特性包括:
-
服务发现和服务健康监测
Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDK、OpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODO 或HTTP&API查找和发现服务。
Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。
-
动态配置服务
动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。
动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。
配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。
-
动态 DNS 服务
动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。
Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表.
-
服务及其元数据管理
Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。
Nacos 地图
一图看懂 Nacos,下面架构部分会详细介绍。
-
特性大图:要从功能特性,非功能特性,全面介绍我们要解的问题域的特性诉求
-
架构大图:通过清晰架构,让您快速进入 Nacos 世界
-
业务大图:利用当前特性可以支持的业务场景,及其最佳实践
-
生态大图:系统梳理 Nacos 和主流技术生态的关系
-
优势大图:展示 Nacos 核心竞争力
-
战略大图:要从战略到战术层面讲 Nacos 的宏观优势
Nacos 生态图
如 Nacos 全景图所示,Nacos 无缝支持一些主流的开源生态,例如
使用 Nacos 简化服务发现、配置管理、服务治理及管理的解决方案,让微服务的发现、管理、共享、组合更加容易。
关于如何在这些生态中使用 Nacos,请参考以下文档:
Nacos 概念
NOTE: Nacos 引入了一些基本的概念,系统性的了解一下这些概念可以帮助您更好的理解和正确的使用 Nacos 产品。
地域
物理的数据中心,资源创建成功后不能更换。
可用区
同一地域内,电力和网络互相独立的物理区域。同一可用区内,实例的网络延迟较低。
接入点
地域的某个服务的入口域名。
命名空间
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
配置
在系统开发过程中,开发者通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成。配置变更是调整系统运行时的行为的有效手段。
配置管理
系统配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动。
配置项
一个具体的可配置的参数与其值域,通常以 param-key=param-value 的形式存在。例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|ERROR) 就是一个配置项。
配置集
一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。
配置集 ID
Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。
配置分组
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
配置快照
Nacos 的客户端 SDK 会在本地生成配置的快照。当客户端无法连接到 Nacos Server 时,可以使用配置快照显示系统的整体容灾能力。配置快照类似于 Git 中的本地 commit,也类似于缓存,会在适当的时机更新,但是并没有缓存过期(expiration)的概念。
服务
通过预定义接口网络访问的提供给客户端的软件功能。
服务名
服务提供的标识,通过该标识可以唯一确定其指代的服务。
服务注册中心
存储服务实例和服务负载均衡策略的数据库。
服务发现
在计算机网络上,(通常使用服务名)对服务下的实例的地址和元数据进行探测,并以预先定义的接口提供给客户端进行查询。
元信息
Nacos数据(如配置和服务)描述信息,如服务版本、权重、容灾策略、负载均衡策略、鉴权配置、各种自定义标签 (label),从作用范围来看,分为服务级别的元信息、集群的元信息及实例的元信息。
应用
用于标识服务提供方的服务的属性。
服务分组
不同的服务可以归类到同一分组。
虚拟集群
同一个服务下的所有服务实例组成一个默认集群, 集群可以被进一步按需求划分,划分的单位可以是虚拟集群。
实例
提供一个或多个服务的具有可访问网络地址(IP:Port)的进程。
权重
实例级别的配置。权重为浮点数。权重越大,分配给该实例的流量越大。
健康检查
以指定方式检查服务下挂载的实例 (Instance) 的健康度,从而确认该实例 (Instance) 是否能提供服务。根据检查结果,实例 (Instance) 会被判断为健康或不健康。对服务发起解析请求时,不健康的实例 (Instance) 不会返回给客户端。
健康保护阈值
为了防止因过多实例 (Instance) 不健康导致流量全部流向健康实例 (Instance) ,继而造成流量压力把健康实例 (Instance) 压垮并形成雪崩效应,应将健康保护阈值定义为一个 0 到 1 之间的浮点数。当域名健康实例数 (Instance) 占总服务实例数 (Instance) 的比例小于该值时,无论实例 (Instance) 是否健康,都会将这个实例 (Instance) 返回给客户端。这样做虽然损失了一部分流量,但是保证了集群中剩余健康实例 (Instance) 能正常工作。
Nacos 架构
基本架构及概念
服务 (Service)
服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service。
服务注册中心 (Service Registry)
服务注册中心,它是服务,其实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查 API 来验证它是否能够处理请求。
服务元数据 (Service Metadata)
服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据。
服务提供方 (Service Provider)
是指提供可复用和可调用服务的应用方。
服务消费方 (Service Consumer)
是指会发起对某个服务调用的应用方。
配置 (Configuration)
在系统开发过程中通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成这个步骤。配置变更是调整系统运行时的行为的有效手段之一。
配置管理 (Configuration Management)
在数据中心中,系统中所有配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动统称为配置管理。
名字服务 (Naming Service)
提供分布式系统中所有对象(Object)、实体(Entity)的“名字”到关联的元数据之间的映射管理服务,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的2大场景。
配置服务 (Configuration Service)
在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。
更多概念...
逻辑架构及其组件介绍
-
服务管理:实现服务CRUD,域名CRUD,服务健康状态检查,服务权重管理等功能
-
配置管理:实现配置管CRUD,版本管理,灰度管理,监听管理,推送轨迹,聚合数据等功能
-
元数据管理:提供元数据CURD 和打标能力
-
插件机制:实现三个模块可分可合能力,实现扩展点SPI机制
-
事件机制:实现异步化事件通知,sdk数据变化异步通知等逻辑
-
日志模块:管理日志分类,日志级别,日志可移植性(尤其避免冲突),日志格式,异常码+帮助文档
-
回调机制:sdk通知数据,通过统一的模式回调用户处理。接口和数据结构需要具备可扩展性
-
寻址模式:解决ip,域名,nameserver、广播等多种寻址模式,需要可扩展
-
推送通道:解决server与存储、server间、server与sdk间推送性能问题
-
容量管理:管理每个租户,分组下的容量,防止存储被写爆,影响服务可用性
-
流量管理:按照租户,分组等多个维度对请求频率,长链接个数,报文大小,请求流控进行控制
-
缓存机制:容灾目录,本地缓存,server缓存机制。容灾目录使用需要工具
-
启动模式:按照单机模式,配置模式,服务模式,dns模式,或者all模式,启动不同的程序+UI
-
一致性协议:解决不同数据,不同一致性要求情况下,不同一致性机制
-
存储模块:解决数据持久化、非持久化存储,解决数据分片问题
-
Nameserver:解决namespace到clusterid的路由问题,解决用户环境与nacos物理环境映射问题
-
CMDB:解决元数据存储,与三方cmdb系统对接问题,解决应用,人,资源关系
-
Metrics:暴露标准metrics数据,方便与三方监控系统打通
-
Trace:暴露标准trace,方便与SLA系统打通,日志白平化,推送轨迹等能力,并且可以和计量计费系统打通
-
接入管理:相当于阿里云开通服务,分配身份、容量、权限过程
-
用户管理:解决用户管理,登录,sso等问题
-
权限管理:解决身份识别,访问控制,角色管理等问题
-
审计系统:扩展接口方便与不同公司审计系统打通
-
通知系统:核心数据变更,或者操作,方便通过SMS系统打通,通知到对应人数据变更
-
OpenAPI:暴露标准Rest风格HTTP接口,简单易用,方便多语言集成
-
Console:易用控制台,做服务管理、配置管理等操作
-
SDK:多语言sdk
-
Agent:dns-f类似模式,或者与mesh等方案集成
-
CLI:命令行对产品进行轻量化管理,像git一样好用
领域模型
数据模型
Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP。
服务领域模型
配置领域模型
围绕配置,主要有两个关联的实体,一个是配置变更历史,一个是服务标签(用于打标分类,方便索引),由 ID 关联。
类视图
Nacos-SDK 类视图
服务部分待续
构建物、部署及启动模式
两种交付工件
Nacos 支持标准 Docker 镜像(TODO: 0.2版本开始支持)及 zip(tar.gz)压缩包的构建物。
两种启动模式
Nacos 支持将注册中心(Service Registry)与配置中心(Config Center) 在一个进程合并部署或者将2者分离部署的两种模式。
免费的公有云服务模式
除了您自己部署和启动 Nacos 服务之外,在云计算时代,Nacos 也支持公有云模式,在阿里云公有云的商业产品(如ACM, EDAS) 中会提供 Nacos 的免费的公有云服务。我们也欢迎和支持其他的公有云提供商提供 Nacos 的公有云服务。
Nacos功能和需求列表
本文列举了目前Nacos支持的主要功能和一些还未支持的需求排期,方便读者了解目前Nacos已经支持和计划支持的能力,同时所有计划支持的能力都开放给开发者进行认领,本文末有详细的认领教程。
在下面的表格中,每个需求都有一个状态的标志,包含若干种取值,各种取值的含义如下:
-
状态的取值:
-
不支持:该功能还不支持,且没有在现在的时间表里有任何排期;
-
排期中:该功能还不支持,但是已经放到了时间表里,有希望在后面的某个版本支持;
-
设计中:表示该功能正在方案设计中,方案的草稿和终稿都会开放访问,供大家讨论;
-
开发中:表示该功能设计方案已经确定,正在有对应的开发者进行开发,会在接下来的某个版本正式发布;
-
beta:该功能已经发布,但是未经过大规模的用户验证,还不能确保稳定性;
-
稳定:表示已经迭代至少4个版本,目前没有反馈重大缺陷;
服务发现
代码地址:https://github.com/alibaba/nacos/tree/develop/naming
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
服务注册与发现 | nkorange | 稳定 | 0.1.0 |
健康检查(服务端探测、客户端心跳) | xuanyin | 稳定 | 0.1.0 |
路由策略(权重、保护阈值、就近访问) | wangjianwei | 稳定 | 0.1.0 |
配置管理
代码地址:https://github.com/alibaba/nacos/tree/develop/config
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
配置管理(发布、修改、查询、监听配置) | yanlinly | 稳定 | 0.1.0 |
灰度配置 | yanlinly | 稳定 | 1.1.0 |
加密配置 | 不支持 |
元数据管理
代码地址:https://github.com/alibaba/nacos/tree/develop/cmdb
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
对接第三方CMDB | nkorange | beta | 0.7.0 |
地址服务器
代码地址:https://github.com/alibaba/nacos/tree/develop/address
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
支持Nacos寻址 | pbting | beta | 1.1.0 |
Nacos内核
代码地址:https://github.com/alibaba/nacos/tree/develop/core
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
去除MySQL依赖 | chuntaojun | 设计中 | |
Raft协议替换成JRaft | chuntaojun | 设计中 | |
异步通知机制统一 | wfnuser | 设计中 | |
线程模块统一 | 排期中 | ||
传输通道统一 | nkorange | 设计中 | |
推送模块统一 | satjd | 设计中 | |
启动模块统一 | 排期中 |
安全与稳定性
代码地址:https://github.com/alibaba/nacos
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
命名空间模块下沉为公共模块 | 排期中 | ||
权限控制,包括认证与鉴权 | nkorange | 开发中 | 1.2.0 |
操作审计与记录 | 排期中 | ||
支持加密传输 | 排期中 | ||
OpenTracing对接 | 排期中 | ||
metrics收集 | TsingLiang | 稳定 | 0.8.0 |
缓存容灾机制统一 | 排期中 | ||
支持命令行运维 | 排期中 | ||
数据自动备份 | 排期中 | ||
限流模块 | 排期中 | ||
容量管理 | 排期中 |
代码质量
代码地址:https://github.com/alibaba/nacos
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
工具类模块统一 | 排期中 | ||
常量定义统一 | 排期中 | ||
异常处理模块统一 | 排期中 | ||
日志模块统一 | 排期中 | ||
系统参数模块统一 | 排期中 | ||
依赖统一 | 排期中 | ||
状态码模块统一 | KeRan213539 | 设计中 |
云原生
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
对接Istio | nkorange | beta | 1.1.4 |
对接ConfigMap | 排期中 | ||
对接CoreDNS | JianweiWang | beta | 0.1.0 |
对接SPIFFE | 排期中 |
客户端
客户端支持包含了目前已知的Nacos多语言客户端及Spring生态的相关客户端,除了Java客户端和Go客户端,其他均为社区热心贡献者开发,如果您有新的语言的客户端,或者有目前已经支持的语言的客户端的另外一个实现,欢迎在github上留言进行登记。
描述 | 主要开发者 | 状态 |
---|---|---|
Java客户端 | Nacos | 稳定 |
Go客户端 | atlanssia, lzp0412 | 稳定 |
Node.js客户端 | czy88840616, gxcsoccer | 稳定 |
Python客户端 | sanwei | beta |
C#客户端 | catcherwong | 推荐 |
C++客户端 | ||
PHP客户端 | ||
Spring客户端 | chuntaojun | 稳定 |
SpringBoot客户端 | chuntaojun | 稳定 |
Nacos-Docker
代码地址:https://github.com/nacos-group/nacos-docker
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
Docker部署Nacos Server | paderlol | 稳定 | 0.1.0 |
Nacos-K8s
代码地址:https://github.com/nacos-group/nacos-k8s
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
K8s部署Nacos Server | paderlol | 稳定 | 0.1.0 |
Nacos-Sync
代码地址:https://github.com/nacos-group/nacos-sync
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
Nacos与Nacos服务双向同步 | paderlol | 稳定 | 0.1.0 |
Nacos与Zookeeper服务双向同步 | paderlol | 稳定 | 0.3.0 |
Nacos与Eureka服务双向同步 | paderlol | 稳定 | 0.3.0 |
Nacos与Consul服务双向同步 | paderlol | 稳定 | 0.3.0 |
Nacos官网
代码地址:https://github.com/nacos-group/nacos-group.github.io
描述 | 主要开发者 | 状态 | 排期 |
---|---|---|---|
支持页面内锚链接 | 不支持 |
参与共建
参与共建能得到什么?
参与Nacos共建,你将有机会让你的代码被全中国甚至全世界的用户阅读并使用,同时在成为Nacos Committer后(如何成为Nacos Committer可以参考手册),还可以有以下福利:
-
在Nacos官网团队页留名;
-
收到我们带Nacos logo的小礼物,有T恤、水杯、帽衫等等;
-
代表Nacos参加各种线上线下活动,与更多小伙伴交流;
-
更多我们还在筹划中的福利;
如何共建
除了在上面列举的功能和需求,其他的在github仓库上打上了contribution welcome或者help wanted标签的issue,也非常欢迎大家提交代码贡献。加入Nacos 社区核心贡献小组钉钉群23335652,联系群管理员认领需求。
大家提PR的时候有几点需要注意下:
-
比较重大的特性需要有方案文档:https://github.com/alibaba/nacos/issues/858
-
已经阅读并遵守共建规范: https://github.com/alibaba/nacos/blob/master/CONTRIBUTING.md
-
使用github账户提交代码,这样大家才会在contributor列表看到自己的名字;
-
commit信息要带上issue id,这样才能在issue里看到PR的进度;
-
代码中不要出现中文注释,提交前要格式化,并添加必要的集成测试用例和单元测试用例;
-
提PR前运行mvn -Prelease-nacos clean install -U和mvn clean install -Pit-test成功;
任务认领原则:每人一次最多领取两个任务,任务PR合并后,即可开始认领下个任务。
Nacos 快速开始
这个快速开始手册是帮忙您快速在您的电脑上,下载、安装并使用 Nacos。
0.版本选择
您可以在Nacos的release notes及博客中找到每个版本支持的功能的介绍,当前推荐的稳定版本为2.0.3。
1.预备环境准备
Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用:
-
64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
2.下载源码或者安装包
你可以通过源码和发行包两种方式来获取 Nacos。
从 Github 上下载源码方式
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
ls -al distribution/target/
// change the $version to your actual path
cd distribution/target/nacos-server-$version/nacos/bin
下载编译后压缩包方式
您可以从 最新稳定版本 下载 nacos-server-$version.zip
包。
unzip nacos-server-$version.zip 或者 tar -xvf nacos-server-$version.tar.gz
cd nacos/bin
3.启动服务器
Linux/Unix/Mac
启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:
bash startup.sh -m standalone
Windows
启动命令(standalone代表着单机模式运行,非集群模式):
startup.cmd -m standalone
4.服务注册&发现和配置管理
服务注册
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'
服务发现
curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'
发布配置
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"
5.关闭服务器
Linux/Unix/Mac
sh shutdown.sh
Windows
shutdown.cmd
或者双击shutdown.cmd运行文件。
Nacos Spring 快速开始
本文主要面向 Spring 的使用者,通过两个示例来介绍如何使用 Nacos 来实现分布式环境下的配置管理和服务发现。
关于 Nacos Spring 的详细文档请参看:nacos-spring-project。
-
通过 Nacos server 和 Nacos Spring 配置管理模块,实现配置的动态变更;
-
通过 Nacos server 和 Nacos Spring 服务发现模块,实现服务的注册与发现。
前提条件
您需要先下载 Nacos 并启动 Nacos server。操作步骤参见 Nacos 快速入门。
启动配置管理
启动了 Nacos server 后,您就可以参考以下示例代码,为您的 Spring 应用启动 Nacos 配置管理服务了。完整示例代码请参考:nacos-spring-config-example
-
添加依赖。
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>${latest.version}</version>
</dependency>
最新版本可以在 maven 仓库,如 "mvnrepository.com" 中获取。
-
添加
@EnableNacosConfig
注解启用 Nacos Spring 的配置管理服务。以下示例中,我们使用@NacosPropertySource
加载了dataId
为example
的配置源,并开启自动更新:
public class NacosConfiguration {
}
-
通过 Nacos 的
@NacosValue
注解设置属性值。
public class ConfigController {
private boolean useLocalCache;
public boolean get() {
return useLocalCache;
}
}
-
启动 Tomcat,调用
curl http://localhost:8080/config/get
尝试获取配置信息。由于此时还未发布过配置,所以返回内容是false
。 -
通过调用 Nacos Open API 向 Nacos Server 发布配置:dataId 为
example
,内容为useLocalCache=true
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=useLocalCache=true"
-
再次访问
http://localhost:8080/config/get
,此时返回内容为true
,说明程序中的useLocalCache
值已经被动态更新了。
启动服务发现
本节演示如何在您的 Spring 项目中启动 Nacos 的服务发现功能。完整示例代码请参考:nacos-spring-discovery-example
-
添加依赖。
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>${latest.version}</version>
</dependency>
最新版本可以在 maven 仓库,如 "mvnrepository.com" 中获取。
-
通过添加
@EnableNacosDiscovery
注解开启 Nacos Spring 的服务发现功能:
public class NacosConfiguration {
}
-
使用
@NacosInjected
注入 Nacos 的NamingService
实例:
public class DiscoveryController {
private NamingService namingService;
public List<Instance> get(
return namingService.getAllInstances(serviceName);
}
}
-
启动 Tomcat,调用
curl http://localhost:8080/discovery/get?serviceName=example
,此时返回为空 JSON 数组[]
。 -
通过调用 Nacos Open API 向 Nacos server 注册一个名称为
example
服务。
curl -X PUT 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080'
-
再次访问
curl http://localhost:8080/discovery/get?serviceName=example
,此时返回内容为:
[
{
"instanceId": "127.0.0.1#8080#DEFAULT#example",
"ip": "127.0.0.1",
"port": 8080,
"weight": 1.0,
"healthy": true,
"cluster": {
"serviceName": null,
"name": "",
"healthChecker": {
"type": "TCP"
},
"defaultPort": 80,
"defaultCheckPort": 80,
"useIPPort4Check": true,
"metadata": {}
},
"service": null,
"metadata": {}
}
]
相关项目
Nacos Spring Boot 快速开始
本文主要面向 Spring Boot 的使用者,通过两个示例来介绍如何使用 Nacos 来实现分布式环境下的配置管理和服务发现。
关于 Nacos Spring Boot 的详细文档请参看:nacos-spring-boot-project。
-
通过 Nacos Server 和 nacos-config-spring-boot-starter 实现配置的动态变更;
-
通过 Nacos Server 和 nacos-discovery-spring-boot-starter 实现服务的注册与发现。
前提条件
您需要先下载 Nacos 并启动 Nacos server。操作步骤参见 Nacos 快速入门。
启动配置管理
启动了 Nacos server 后,您就可以参考以下示例代码,为您的 Spring Boot 应用启动 Nacos 配置管理服务了。完整示例代码请参考:nacos-spring-boot-config-example
-
添加依赖。
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
注意:版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
-
在
application.properties
中配置 Nacos server 的地址:
nacos.config.server-addr=127.0.0.1:8848
-
使用
@NacosPropertySource
加载dataId
为example
的配置源,并开启自动更新:
@SpringBootApplication
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfigApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConfigApplication.class, args);
}
}
-
通过 Nacos 的
@NacosValue
注解设置属性值。
public class ConfigController {
private boolean useLocalCache;
public boolean get() {
return useLocalCache;
}
}
-
启动
NacosConfigApplication
,调用curl http://localhost:8080/config/get
,返回内容是false
。 -
通过调用 Nacos Open API 向 Nacos server 发布配置:dataId 为
example
,内容为useLocalCache=true
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=useLocalCache=true"
-
再次访问
http://localhost:8080/config/get
,此时返回内容为true
,说明程序中的useLocalCache
值已经被动态更新了。
启动服务发现
本节演示如何在您的 Spring Boot 项目中启动 Nacos 的服务发现功能。完整示例代码请参考:nacos-spring-boot-discovery-example
-
添加依赖。
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
注意:版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
-
在
application.properties
中配置 Nacos server 的地址:
nacos.discovery.server-addr=127.0.0.1:8848
-
使用
@NacosInjected
注入 Nacos 的NamingService
实例:
public class DiscoveryController {
private NamingService namingService;
public List<Instance> get(
return namingService.getAllInstances(serviceName);
}
}
public class NacosDiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(NacosDiscoveryApplication.class, args);
}
}
-
启动
NacosDiscoveryApplication
,调用curl http://localhost:8080/discovery/get?serviceName=example
,此时返回为空 JSON 数组[]
。 -
通过调用 Nacos Open API 向 Nacos server 注册一个名称为
example
服务
curl -X PUT 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080'
-
再次访问
curl http://localhost:8080/discovery/get?serviceName=example
,此时返回内容为:
[
{
"instanceId": "127.0.0.1-8080-DEFAULT-example",
"ip": "127.0.0.1",
"port": 8080,
"weight": 1.0,
"healthy": true,
"cluster": {
"serviceName": null,
"name": "",
"healthChecker": {
"type": "TCP"
},
"defaultPort": 80,
"defaultCheckPort": 80,
"useIPPort4Check": true,
"metadata": {}
},
"service": null,
"metadata": {}
}
]
相关项目
Nacos Spring Cloud 快速开始
本文主要面向 Spring Cloud 的使用者,通过两个示例来介绍如何使用 Nacos 来实现分布式环境下的配置管理和服务注册发现。
关于 Nacos Spring Cloud 的详细文档请参看:Nacos Config 和 Nacos Discovery。
-
通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 实现配置的动态变更。
-
通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。
前提条件
您需要先下载 Nacos 并启动 Nacos server。操作步骤参见 Nacos 快速入门
启动配置管理
启动了 Nacos server 后,您就可以参考以下示例代码,为您的 Spring Cloud 应用启动 Nacos 配置管理服务了。完整示例代码请参考:nacos-spring-cloud-config-example
-
添加依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>${latest.version}</version>
</dependency>
注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。
更多版本对应关系参考:版本说明 Wiki
-
在
bootstrap.properties
中配置 Nacos server 的地址和应用名
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name=example
说明:之所以需要配置 spring.application.name
,是因为它是构成 Nacos 配置管理 dataId
字段的一部分。
在 Nacos Spring Cloud 中,dataId
的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
-
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置。 -
spring.profiles.active
即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当spring.profiles.active
为空时,对应的连接符-
也将不存在,dataId 的拼接格式变成${prefix}.${file-extension}
-
file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。
-
通过 Spring Cloud 原生注解
@RefreshScope
实现配置自动更新:
public class ConfigController {
private boolean useLocalCache;
public boolean get() {
return useLocalCache;
}
}
-
首先通过调用 Nacos Open API 向 Nacos Server 发布配置:dataId 为
example.properties
,内容为useLocalCache=true
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example.properties&group=DEFAULT_GROUP&content=useLocalCache=true"
-
运行
NacosConfigApplication
,调用curl http://localhost:8080/config/get
,返回内容是true
。 -
再次调用 Nacos Open API 向 Nacos server 发布配置:dataId 为
example.properties
,内容为useLocalCache=false
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example.properties&group=DEFAULT_GROUP&content=useLocalCache=false"
-
再次访问
http://localhost:8080/config/get
,此时返回内容为false
,说明程序中的useLocalCache
值已经被动态更新了。
启动服务发现
本节通过实现一个简单的 echo service
演示如何在您的 Spring Cloud 项目中启用 Nacos 的服务发现功能,如下图示:
完整示例代码请参考:nacos-spring-cloud-discovery-example
-
添加依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${latest.version}</version>
</dependency>
注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。
更多版本对应关系参考:版本说明 Wiki
-
配置服务提供者,从而服务提供者可以通过 Nacos 的服务注册发现功能将其服务注册到 Nacos server 上。
i. 在 application.properties
中配置 Nacos server 的地址:
server.port=8070
spring.application.name=service-provider
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
ii. 通过 Spring Cloud 原生注解 @EnableDiscoveryClient
开启服务注册发现功能:
public class NacosProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NacosProviderApplication.class, args);
}
class EchoController {
public String echo(
return "Hello Nacos Discovery " + string;
}
}
}
-
配置服务消费者,从而服务消费者可以通过 Nacos 的服务注册发现功能从 Nacos server 上获取到它要调用的服务。
i. 在 application.properties
中配置 Nacos server 的地址:
server.port=8080
spring.application.name=service-consumer
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
ii. 通过 Spring Cloud 原生注解 @EnableDiscoveryClient
开启服务注册发现功能。给 RestTemplate 实例添加 @LoadBalanced
注解,开启 @LoadBalanced
与 Ribbon 的集成:
public class NacosConsumerApplication {
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(NacosConsumerApplication.class, args);
}
public class TestController {
private final RestTemplate restTemplate;
public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}
public String echo(
return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
}
}
}
-
启动
ProviderApplication
和ConsumerApplication
,调用http://localhost:8080/echo/2018
,返回内容为Hello Nacos Discovery 2018
。
相关项目
Nacos Docker 快速开始
操作步骤
-
Clone 项目
git clone https://github.com/nacos-group/nacos-docker.git
cd nacos-docker
-
单机模式 Derby
docker-compose -f example/standalone-derby.yaml up
-
单机模式 MySQL
如果希望使用MySQL5.7
docker-compose -f example/standalone-mysql-5.7.yaml up
如果希望使用MySQL8
docker-compose -f example/standalone-mysql-8.yaml up
-
集群模式
docker-compose -f example/cluster-hostname.yaml up
-
服务注册
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'
-
服务发现
curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'
-
发布配置
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"
-
Nacos 控制台
Common property configuration
name | description | option |
---|---|---|
MODE | cluster模式/standalone模式 | cluster/standalone default cluster |
NACOS_SERVERS | nacos cluster地址 | eg. ip1,ip2,ip3 |
PREFER_HOST_MODE | 是否支持hostname | hostname/ip default ip |
NACOS_SERVER_PORT | nacos服务器端口 | default 8848 |
NACOS_SERVER_IP | 多网卡下的自定义nacos服务器IP | |
SPRING_DATASOURCE_PLATFORM | standalone 支持 mysql | mysql / empty default empty |
MYSQL_MASTER_SERVICE_HOST | mysql 主节点host | |
MYSQL_MASTER_SERVICE_PORT | mysql 主节点端口 | default : 3306 |
MYSQL_MASTER_SERVICE_DB_NAME | mysql 主节点数据库 | |
MYSQL_MASTER_SERVICE_USER | 数据库用户名 | |
MYSQL_MASTER_SERVICE_PASSWORD | 数据库密码 | |
MYSQL_SLAVE_SERVICE_HOST | mysql从节点host | |
MYSQL_SLAVE_SERVICE_PORT | mysql从节点端口 | default :3306 |
MYSQL_DATABASE_NUM | 数据库数量 | default :2 |
JVM_XMS | -Xms | default :2g |
JVM_XMX | -Xmx | default :2g |
JVM_XMN | -Xmn | default :1g |
JVM_MS | -XX:MetaspaceSize | default :128m |
JVM_MMS | -XX:MaxMetaspaceSize | default :320m |
NACOS_DEBUG | 开启远程调试 | y/n default :n |
TOMCAT_ACCESSLOG_ENABLED | server.tomcat.accesslog.enabled | default :false |
Nacos + Grafana + Prometheus
参考:Nacos监控指南
Note: grafana创建一个新数据源时,数据源地址必须是 http://prometheus:9090
相关项目
Dubbo 融合 Nacos 成为注册中心
Nacos 作为 Dubbo 生态系统中重要的注册中心实现,本文将会介绍如何进行 Dubbo 对接 Nacos 注册中心的工作。
预备工作
请确保后台已经启动 Nacos 服务,可先行参考 Nacos 快速入门。
快速上手
Dubbo 融合 Nacos 成为注册中心的操作步骤非常简单,大致步骤可分为“增加 Maven 依赖”以及“配置注册中心“。
增加 Maven 依赖
只需要依赖Dubbo客户端即可,关于推荐的使用版本,请参考Dubbo官方文档或者咨询Dubbo开发人员:
<dependencies>
...
<!-- Dubbo dependency -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>[latest version]</version>
</dependency>
<!-- 使用Spring装配方式时可选: -->
<dependency>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-context-support</artifactId>
<version>[latest version]</version>
</dependency>
...
</dependencies>
配置注册中心
假设您 Dubbo 应用使用 Spring Framework 装配,将有两种配置方法可选,分别为:Dubbo Spring 外部化配置以及 Spring XML 配置文件以及,笔者强烈推荐前者。
Dubbo Spring 外部化配置
Dubbo Spring 外部化配置是由 Dubbo 2.5.8
引入的新特性,可通过 Spring Environment
属性自动地生成并绑定 Dubbo 配置 Bean,实现配置简化,并且降低微服务开发门槛。
假设您 Dubbo 应用的使用 Zookeeper 作为注册中心,并且其服务器 IP 地址为:10.20.153.10
,同时,该注册地址作为 Dubbo 外部化配置属性存储在 dubbo-config.properties
文件,如下所示:
## application
dubbo.application.name = your-dubbo-application
## Zookeeper registry address
dubbo.registry.address = zookeeper://10.20.153.10:2181
...
假设您的 Nacos Server 同样运行在服务器 10.20.153.10
上,并使用默认 Nacos 服务端口 8848
,您只需将 dubbo.registry.address
属性调整如下:
## 其他属性保持不变
## Nacos registry address
dubbo.registry.address = nacos://10.20.153.10:8848
##如果要使用自己创建的命名空间可以使用下面2种方式
#dubbo.registry.address = nacos://10.20.153.10:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
#dubbo.registry.parameters.namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
...
随后,重启您的 Dubbo 应用,Dubbo 的服务提供和消费信息在 Nacos 控制台中可以显示:
如图所示,服务名前缀为 providers:
的信息为服务提供者的元信息,consumers:
则代表服务消费者的元信息。点击“详情”可查看服务状态详情:
如果您正在使用 Spring XML 配置文件装配 Dubbo 注册中心的话,请参考下一节。
Spring XML 配置文件
同样,假设您 Dubbo 应用的使用 Zookeeper 作为注册中心,并且其服务器 IP 地址为:10.20.153.10
,并且装配 Spring Bean 在 XML 文件中,如下所示:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="dubbo-provider-xml-demo" />
<!-- 使用 Zookeeper 注册中心 -->
<dubbo:registry address="zookeeper://10.20.153.10:2181" />
...
</beans>
与 Dubbo Spring 外部化配置 配置类似,只需要调整 address
属性配置即可:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="dubbo-provider-xml-demo" />
<!-- 使用 Nacos 注册中心 -->
<dubbo:registry address="nacos://10.20.153.10:8848" />
<!-- 如果要使用自己创建的命名空间可以使用下面配置 -->
<!-- <dubbo:registry address="nacos://10.20.153.10:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932" /> -->
...
</beans>
重启 Dubbo 应用后,您同样也能发现服务提供方和消费方的注册元信息呈现在 Nacos 控制台中:
您是否绝对配置或切换 Nacos 注册中心超级 Easy 呢?如果您仍旧意犹未尽或者不甚明白的话,可参考以下完整的示例。
完整示例
以上图片中的元数据源于 Dubbo Spring 注解驱动示例以及 Dubbo Spring XML 配置驱动示例,下面将分别介绍两者,您可以选择自己偏好的编程模型。在正式讨论之前,先来介绍两者的预备工作,因为它们皆依赖 Java 服务接口和实现。同时,请确保本地(127.0.0.1
)环境已启动 Nacos 服务。
示例接口与实现
首先定义示例接口,如下所示:
package com.alibaba.dubbo.demo.service;
/**
* DemoService
*
* @since 2.6.5
*/
public interface DemoService {
String sayName(String name);
}
提供以上接口的实现类:
package com.alibaba.dubbo.demo.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.rpc.RpcContext;
import org.springframework.beans.factory.annotation.Value;
/**
* Default {@link DemoService}
*
* @since 2.6.5
*/
public class DefaultService implements DemoService {
private String serviceName;
public String sayName(String name) {
RpcContext rpcContext = RpcContext.getContext();
return String.format("Service [name :%s , port : %d] %s(\"%s\") : Hello,%s",
serviceName,
rpcContext.getLocalPort(),
rpcContext.getMethodName(),
name,
name);
}
}
接口与实现准备妥当后,下面将采用注解驱动和 XML 配置驱动各自实现。
Spring 注解驱动示例
Dubbo 2.5.7
重构了 Spring 注解驱动的编程模型。
服务提供方注解驱动实现
-
定义 Dubbo 提供方外部化配置属性源 -
provider-config.properties
## application
dubbo.application.name = dubbo-provider-demo
## Nacos registry address
dubbo.registry.address = nacos://127.0.0.1:8848
##如果要使用自己创建的命名空间可以使用下面2种方式
#dubbo.registry.address = nacos://127.0.0.1:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
#dubbo.registry.parameters.namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
## Dubbo Protocol
dubbo.protocol.name = dubbo
dubbo.protocol.port = -1
# Provider @Service version
demo.service.version=1.0.0
demo.service.name = demoService
-
实现服务提供方引导类 -
DemoServiceProviderBootstrap
package com.alibaba.dubbo.demo.provider;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import com.alibaba.dubbo.demo.service.DemoService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
import java.io.IOException;
/**
* {@link DemoService} provider demo
*/
public class DemoServiceProviderBootstrap {
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(DemoServiceProviderBootstrap.class);
context.refresh();
System.out.println("DemoService provider is starting...");
System.in.read();
}
}
其中注解 @EnableDubbo
激活 Dubbo 注解驱动以及外部化配置,其 scanBasePackages
属性扫描指定 Java 包,将所有标注 @Service
的服务接口实现类暴露为 Spring Bean,随即被导出 Dubbo 服务。
@PropertySource
是 Spring Framework 3.1 引入的标准导入属性配置资源注解,它将为 Dubbo 提供外部化配置。
服务消费方注解驱动实现
-
定义 Dubbo 消费方外部化配置属性源 -
consumer-config.properties
## Dubbo Application info
dubbo.application.name = dubbo-consumer-demo
## Nacos registry address
dubbo.registry.address = nacos://127.0.0.1:8848
##如果要使用自己创建的命名空间可以使用下面2种方式
#dubbo.registry.address = nacos://127.0.0.1:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
#dubbo.registry.parameters.namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
# @Reference version
demo.service.version= 1.0.0
同样地,dubbo.registry.address
属性指向 Nacos 注册中心,其他 Dubbo 服务相关的元信息通过 Nacos 注册中心获取。
-
实现服务消费方引导类 -
DemoServiceConsumerBootstrap
package com.alibaba.dubbo.demo.consumer;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import com.alibaba.dubbo.demo.service.DemoService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
import javax.annotation.PostConstruct;
import java.io.IOException;
/**
* {@link DemoService} consumer demo
*/
public class DemoServiceConsumerBootstrap {
private DemoService demoService;
public void init() {
for (int i = 0; i < 10; i++) {
System.out.println(demoService.sayName("小马哥(mercyblitz)"));
}
}
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(DemoServiceConsumerBootstrap.class);
context.refresh();
context.close();
}
}
同样地,@EnableDubbo
注解激活 Dubbo 注解驱动和外部化配置,不过当前属于服务消费者,无需指定 Java 包名扫描标注 @Service
的服务实现。
@Reference
是 Dubbo 远程服务的依赖注入注解,需要服务提供方和消费端约定接口(interface)、版本(version)以及分组(group)信息。在当前服务消费示例中,DemoService
的服务版本来源于属性配置文件 consumer-config.properties
。
@PostConstruct
部分代码则说明当 DemoServiceConsumerBootstrap
Bean 初始化时,执行十次 Dubbo 远程方法调用。
运行注解驱动示例
在本地启动两次 DemoServiceProviderBootstrap
,注册中心将出现两个健康服务:
再运行 DemoServiceConsumerBootstrap
,运行结果如下:
Service [name :demoService , port : 20880] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20881] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20880] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20880] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20881] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20881] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20880] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20880] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20881] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :demoService , port : 20881] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
运行无误,并且服务消费方使用了负载均衡策略,将十次 RPC 调用平均分摊到两个 Dubbo 服务提供方实例中。
Spring XML 配置驱动示例
Spring XML 配置驱动是传统 Spring 装配组件的编程模型。
服务提供方 XML 配置驱动
-
定义服务提供方 XML 上下文配置文件 -
/META-INF/spring/dubbo-provider-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="dubbo-provider-xml-demo"/>
<!-- 使用 Nacos 注册中心 -->
<dubbo:registry address="nacos://127.0.0.1:8848"/>
<!-- 如果要使用自己创建的命名空间可以使用下面配置 -->
<!-- <dubbo:registry address="nacos://127.0.0.1:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932" /> -->
<!-- 用dubbo协议在随机端口暴露服务 -->
<dubbo:protocol name="dubbo" port="-1"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.alibaba.dubbo.demo.service.DemoService" ref="demoService" version="2.0.0"/>
<!-- 和本地bean一样实现服务 -->
<bean id="demoService" class="com.alibaba.dubbo.demo.service.DefaultService"/>
</beans>
-
实现服务提供方引导类 -
DemoServiceProviderXmlBootstrap
package com.alibaba.dubbo.demo.provider;
import com.alibaba.dubbo.demo.service.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* {@link DemoService} provider demo XML bootstrap
*/
public class DemoServiceProviderXmlBootstrap {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
context.setConfigLocation("/META-INF/spring/dubbo-provider-context.xml");
context.refresh();
System.out.println("DemoService provider (XML) is starting...");
System.in.read();
}
}
服务消费方 XML 配置驱动
-
定义服务消费方 XML 上下文配置文件 -
/META-INF/spring/dubbo-consumer-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="dubbo-consumer-xml-demo"/>
<!-- 使用 Nacos 注册中心 -->
<dubbo:registry address="nacos://127.0.0.1:8848"/>
<!-- 如果要使用自己创建的命名空间可以使用下面配置 -->
<!-- <dubbo:registry address="nacos://127.0.0.1:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932" /> -->
<!-- 引用服务接口 -->
<dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.service.DemoService" version="2.0.0"/>
</beans>
-
实现服务消费方引导类 -
DemoServiceConsumerXmlBootstrap
package com.alibaba.dubbo.demo.consumer;
import com.alibaba.dubbo.demo.service.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* {@link DemoService} consumer demo XML bootstrap
*/
public class DemoServiceConsumerXmlBootstrap {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
context.setConfigLocation("/META-INF/spring/dubbo-consumer-context.xml");
context.refresh();
System.out.println("DemoService consumer (XML) is starting...");
DemoService demoService = context.getBean("demoService", DemoService.class);
for (int i = 0; i < 10; i++) {
System.out.println(demoService.sayName("小马哥(mercyblitz)"));
}
context.close();
}
}
运行 XML 配置驱动示例
同样地,先启动两个 DemoServiceProviderXmlBootstrap
引导类,观察 Nacos 注册中心服务提供者变化:
XML 配置驱动的服务版本为 2.0.0
,因此注册服务无误。
再运行服务消费者引导类 DemoServiceConsumerXmlBootstrap
,观察控制台输出内容:
Service [name :null , port : 20882] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20882] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20883] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20882] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20882] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20883] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20882] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20883] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20883] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
Service [name :null , port : 20883] sayName("小马哥(mercyblitz)") : Hello,小马哥(mercyblitz)
结果同样运行和负载均衡正常,不过由于当前示例尚未添加属性 demo.service.name
的缘故,因此,“name”部分信息输出为 null
。
如果您关注或喜爱 Dubbo 以及 Nacos 等开源工程,不妨为它们点 “star”,加油打气链接:
-
Apache Dubbo:https://github.com/apache/dubbo
-
Dubbo Nacos Registry:https://github.com/apache/dubbo/tree/master/dubbo-registry/dubbo-registry-nacos
-
Alibaba Nacos:https://github.com/alibaba/nacos
Kubernetes Nacos
本项目包含一个可构建的Nacos Docker Image,旨在利用StatefulSets在Kubernetes上部署Nacos
快速开始
-
Clone 项目
git clone https://github.com/nacos-group/nacos-k8s.git
-
简单例子
如果你使用简单方式快速启动,请注意这是没有使用持久化卷的,可能存在数据丢失风险:
cd nacos-k8s
chmod +x quick-startup.sh
./quick-startup.sh
-
测试
-
服务注册
curl -X PUT 'http://cluster-ip:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'
-
服务发现
curl -X GET 'http://cluster-ip:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'
-
发布配置
curl -X POST "http://cluster-ip:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=helloWorld"
-
获取配置
curl -X GET "http://cluster-ip:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"
-
高级使用
在高级使用中,Nacos在K8S拥有自动扩容缩容和数据持久特性,请注意如果需要使用这部分功能请使用PVC持久卷,Nacos的自动扩容缩容需要依赖持久卷,以及数据持久化也是一样,本例中使用的是NFS来使用PVC.
部署 NFS
-
创建角色
kubectl create -f deploy/nfs/rbac.yaml
如果的K8S命名空间不是default,请在部署RBAC之前执行以下脚本:
# Set the subject of the RBAC objects to the current namespace where the provisioner is being deployed
$ NS=$(kubectl config get-contexts|grep -e "^\*" |awk '{print $5}')
$ NAMESPACE=${NS:-default}
$ sed -i'' "s/namespace:.*/namespace: $NAMESPACE/g" ./deploy/nfs/rbac.yaml
-
创建
ServiceAccount
和部署NFS-Client Provisioner
kubectl create -f deploy/nfs/deployment.yaml
-
创建 NFS StorageClass
kubectl create -f deploy/nfs/class.yaml
-
验证NFS部署成功
kubectl get pod -l app=nfs-client-provisioner
部署数据库
-
部署主库
cd nacos-k8s
kubectl create -f deploy/mysql/mysql-master-nfs.yaml
-
部署从库
cd nacos-k8s
kubectl create -f deploy/mysql/mysql-slave-nfs.yaml
-
验证数据库是否正常工作
# master
kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-master-gf2vd 1/1 Running 0 111m
# slave
kubectl get pod
mysql-slave-kf9cb 1/1 Running 0 110m
部署Nacos
-
修改 deploy/nacos/nacos-pvc-nfs.yaml
data
mysql.master.db.name
mysql.master.port
mysql.slave.port
mysql.master.user
mysql.master.password
-
创建 Nacos
kubectl create -f nacos-k8s/deploy/nacos/nacos-pvc-nfs.yaml
-
验证Nacos节点启动成功
kubectl get pod -l app=nacos
NAME READY STATUS RESTARTS AGE
nacos-0 1/1 Running 0 19h
nacos-1 1/1 Running 0 19h
nacos-2 1/1 Running 0 19h
扩容测试
-
在扩容前,使用
kubectl exec
获取在pod中的Nacos集群配置文件信息
for i in 0 1; do echo nacos-$i; kubectl exec nacos-$i cat conf/cluster.conf; done
StatefulSet控制器根据其序数索引为每个Pod提供唯一的主机名。 主机名采用 - 的形式。 因为nacos StatefulSet的副本字段设置为2,所以当前集群文件中只有两个Nacos节点地址
-
使用kubectl scale 对Nacos动态扩容
kubectl scale sts nacos --replicas=3
-
在扩容后,使用
kubectl exec
获取在pod中的Nacos集群配置文件信息
for i in 0 1 2; do echo nacos-$i; kubectl exec nacos-$i cat conf/cluster.conf; done
-
使用
kubectl exec
执行Nacos API 在每台节点上获取当前Leader是否一致
for i in 0 1 2; do echo nacos-$i; kubectl exec nacos-$i curl -X GET "http://localhost:8848/nacos/v1/ns/raft/state"; done
到这里你可以发现新节点已经正常加入Nacos集群当中
例子部署环境
-
机器配置
内网IP | 主机名 | 配置 |
---|---|---|
172.17.79.3 | k8s-master | CentOS Linux release 7.4.1708 (Core) Single-core processor Mem 4G Cloud disk 40G |
172.17.79.4 | node01 | CentOS Linux release 7.4.1708 (Core) Single-core processor Mem 4G Cloud disk 40G |
172.17.79.5 | node02 | CentOS Linux release 7.4.1708 (Core) Single-core processor Mem 4G Cloud disk 40G |
-
Kubernetes 版本:1.12.2 (如果你和我一样只使用了三台机器,那么记得开启master节点的部署功能)
-
NFS 版本:4.1 在k8s-master进行安装Server端,并且指定共享目录,本项目指定的/data/nfs-share
-
Git
限制
-
必须要使用持久卷,否则会出现数据丢失的情况
项目目录
目录 | 描述 |
---|---|
plugin |
帮助Nacos集群进行动态扩容的插件Docker镜像源码 |
deploy |
K8s 部署文件 |
配置属性
-
nacos-pvc-nfs.yaml or nacos-quick-start.yaml
名称 | 必要 | 描述 |
---|---|---|
mysql.master.db.name |
Y | 主库名称 |
mysql.master.port |
N | 主库端口 |
mysql.slave.port |
N | 从库端口 |
mysql.master.user |
Y | 主库用户名 |
mysql.master.password |
Y | 主库密码 |
NACOS_REPLICAS |
N | 确定执行Nacos启动节点数量,如果不适用动态扩容插件,就必须配置这个属性,否则使用扩容插件后不会生效 |
NACOS_SERVER_PORT |
N | Nacos 端口 |
PREFER_HOST_MODE |
Y | 启动Nacos集群按域名解析 |
-
nfs deployment.yaml
名称 | 必要 | 描述 |
---|---|---|
NFS_SERVER |
Y | NFS 服务端地址 |
NFS_PATH |
Y | NFS 共享目录 |
server |
Y | NFS 服务端地址 |
path |
Y | NFS 共享目录 |
-
mysql
名称 | 必要 | 描述 |
---|---|---|
MYSQL_ROOT_PASSWORD |
N | ROOT 密码 |
MYSQL_DATABASE |
Y | 数据库名称 |
MYSQL_USER |
Y | 数据库用户名 |
MYSQL_PASSWORD |
Y | 数据库密码 |
MYSQL_REPLICATION_USER |
Y | 数据库复制用户 |
MYSQL_REPLICATION_PASSWORD |
Y | 数据库复制用户密码 |
Nfs:server |
N | NFS 服务端地址,如果使用本地部署不需要配置 |
Nfs:path |
N | NFS 共享目录,如果使用本地部署不需要配置 |
NacosSync 介绍
介绍
-
NacosSync是一个支持多种注册中心的同步组件,基于Spring boot开发框架,数据层采用Spring Data JPA,遵循了标准的JPA访问规范,支持多种数据源存储,默认使用Hibernate实现,更加方便的支持表的自动创建更新
-
使用了高效的事件异步驱动模型, 支持多种自定义事件,使得同步任务处理的延时控制在3s,8C16G的单机能够支持6K的同步任务
-
NacosSync除了单机部署,也提供了高可用的集群部署模式,NacosSync是无状态设计,将任务等状态数据迁移到了数据库,使得集群扩展非常方便
-
抽象出了Sync组件核心接口,通过注解对同步类型进行区分,使得开发者可以很容易的根据自己需求,去扩展不同注册中心,目前已支持的同步类型:
-
Nacos数据同步到Nacos
-
Zookeeper数据同步到Nacos
-
Nacos数据同步到Zookeeper
-
Eureka数据同步到Nacos
-
Consul数据同步到Nacos
-
系统模块架构:
控制台 提供了精简Web操作控制台,支持国际化:
同步任务管理页面
注册中心管理页面
使用场景:
-
多个网络互通的Region之间服务共享,打破Region之间的服务调用限制
-
双向同步功能,支持Dubbo+Zookeeper服务平滑迁移到Dubbo+Naocs,享受Nacos更加优质的服务
Java SDK
概述部分
Maven 坐标
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${version}</version>
</dependency>
配置管理
获取配置
描述
用于服务启动的时候从 Nacos 获取配置。
public String getConfig(String dataId, String group, long timeoutMs) throws NacosException
请求参数
参数名 | 参数类型 | 描述 |
---|---|---|
dataId | string | 配置 ID,采用类似 package.class(如com.taobao.tc.refund.log.level)的命名规则保证全局唯一性,class 部分建议是配置的业务含义。全部字符小写。只允许英文字符和 4 种特殊字符("."、":"、"-"、"_"),不超过 256 字节。 |
group | string | 配置分组,建议填写产品名:模块名(Nacos:Test)保证唯一性,只允许英文字符和4种特殊字符("."、":"、"-"、"_"),不超过128字节。 |
timeout | long | 读取配置超时时间,单位 ms,推荐值 3000。 |
返回值
参数类型 | 描述 |
---|---|
string | 配置值 |
请求示例
try {
String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfig(dataId, group, 5000);
System.out.println(content);
} catch (NacosException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
异常说明
读取配置超时或网络异常,抛出 NacosException 异常。
监听配置
描述
如果希望 Nacos 推送配置变更,可以使用 Nacos 动态监听配置接口来实现。
public void addListener(String dataId, String group, Listener listener)
请求参数
参数名 | 参数类型 | 描述 |
---|---|---|
dataId | string | 配置 ID,采用类似 package.class(如com.taobao.tc.refund.log.level)的命名规则保证全局唯一性,class 部分建议是配置的业务含义。 全部字符小写。只允许英文字符和 4 种特殊字符("."、":"、"-"、"_")。不超过 256 字节。 |
group | string | 配置分组,建议填写产品名:模块名(如 Nacos:Test)保证唯一性。 只允许英文字符和4种特殊字符("."、":"、"-"、"_"),不超过128字节。 |
listener | Listener | 监听器,配置变更进入监听器的回调函数。 |
返回值
参数类型 | 描述 |
---|---|
string | 配置值,初始化或者配置变更的时候通过回调函数返回该值。 |
请求示例
String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfig(dataId, group, 5000);
System.out.println(content);
configService.addListener(dataId, group, new Listener() {
public void receiveConfigInfo(String configInfo) {
System.out.println("recieve1:" + configInfo);
}
public Executor getExecutor() {
return null;
}
});
// 测试让主线程不退出,因为订阅配置是守护线程,主线程退出守护线程就会退出。 正式代码中无需下面代码
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
删除监听
描述
取消监听配置,取消监听后配置不会再推送。
public void removeListener(String dataId, String group, Listener listener)
请求参数
参数名 | 参数类型 | 描述 |
---|---|---|
dataId | string | 配置 ID,采用类似 package.class(如com.taobao.tc.refund.log.level)的命名规则保证全局唯一性,class 部分建议是配置的业务含义。全部字符小写。只允许英文字符和 4 种特殊字符("."、":"、"-"、"_"),不超过 256 字节。 |
group | string | 配置分组 |
listener | ConfigChangeListenerAdapter | 监听器,配置变更进入监听器的回调函数。 |
使用示例
String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
configService.removeListener(dataId, group, yourListener);
发布配置
描述
用于通过程序自动发布 Nacos 配置,以便通过自动化手段降低运维成本。
注意:创建和修改配置时使用的同一个发布接口,当配置不存在时会创建配置,当配置已存在时会更新配置。
public boolean publishConfig(String dataId, String group, String content) throws NacosException;
public boolean publishConfig(String dataId, String group, String content, String type) throws NacosException;
请求参数
参数名 | 参数类型 | 描述 |
---|---|---|
dataId | string | 配置 ID,采用类似 package.class (如 com.taobao.tc.refund.log.level )的命名规则保证全局唯一性。建议根据配置的业务含义来定义 class 部分。全部字符均为小写。只允许英文字符和 4 种特殊字符(“.”、“:”、“-”、“_”),不超过 256 字节。 |
group | string | 配置分组,建议填写产品名:模块名 (如 Nacos:Test )来保证唯一性。只允许英文字符和 4 种特殊字符(“.”、“:”、“-”、“_”),不超过 128 字节。 |
content | string | 配置内容,不超过 100K 字节。 |
type | string | @Since 1.4.1. 配置类型,见 com.alibaba.nacos.api.config.ConfigType ,默认为TEXT |
返回参数
参数类型 | 描述 |
---|---|
boolean | 是否发布成功 |
请求示例
try {
// 初始化配置服务,控制台通过示例代码自动获取下面参数
String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
boolean isPublishOk = configService.publishConfig(dataId, group, "content");
System.out.println(isPublishOk);
} catch (NacosException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
异常说明
读取配置超时或网络异常,抛出 NacosException 异常。
删除配置
描述
用于通过程序自动删除 Nacos 配置,以便通过自动化手段降低运维成本。
注意: 当配置已存在时会删除该配置,当配置不存在时会直接返回成功消息。
public boolean removeConfig(String dataId, String group) throws NacosException
请求参数
参数名 | 参数类型 | 描述 |
---|---|---|
dataId | string | 配置 ID |
group | string | 配置分组 |
返回参数
参数类型 | 描述 |
---|---|
boolean | 是否删除成功 |
请求示例
try {
// 初始化配置服务,控制台通过示例代码自动获取下面参数
String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
boolean isRemoveOk = configService.removeConfig(dataId, group);
System.out.println(isRemoveOk);
} catch (NacosException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
异常说明
读取配置超时或网络异常,抛出 NacosException 异常。
服务发现SDK
注册实例
描述注册一个实例到服务。
void registerInstance(String serviceName, String ip, int port) throws NacosException;
void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;
void registerInstance(String serviceName, Instance instance) throws NacosException;
请求参数
名称 | 类型 | 描述 |
---|---|---|
serviceName | 字符串 | 服务名 |
ip | 字符串 | 服务实例IP |
port | int | 服务实例port |
clusterName | 字符串 | 集群名 |
instance | 参见代码注释 | 实例属性 |
返回参数
无
请求示例
NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
naming.registerInstance("nacos.test.3", "11.11.11.11", 8888, "TEST1");
Instance instance = new Instance();
instance.setIp("55.55.55.55");
instance.setPort(9999);
instance.setHealthy(false);
instance.setWeight(2.0);
Map<String, String> instanceMeta = new HashMap<>();
instanceMeta.put("site", "et2");
instance.setMetadata(instanceMeta);
Service service = new Service("nacos.test.4");
service.setApp("nacos-naming");
service.sethealthCheckMode("server");
service.setEnableHealthCheck(true);
service.setProtectThreshold(0.8F);
service.setGroup("CNCF");
Map<String, String> serviceMeta = new HashMap<>();
serviceMeta.put("symmetricCall", "true");
service.setMetadata(serviceMeta);
instance.setService(service);
Cluster cluster = new Cluster();
cluster.setName("TEST5");
AbstractHealthChecker.Http healthChecker = new AbstractHealthChecker.Http();
healthChecker.setExpectedResponseCode(400);
healthChecker.setCurlHost("USer-Agent|Nacos");
healthChecker.setCurlPath("/xxx.html");
cluster.setHealthChecker(healthChecker);
Map<String, String> clusterMeta = new HashMap<>();
clusterMeta.put("xxx", "yyyy");
cluster.setMetadata(clusterMeta);
instance.setCluster(cluster);
naming.registerInstance("nacos.test.4", instance);
注销实例
描述
删除服务下的一个实例。
void deregisterInstance(String serviceName, String ip, int port) throws NacosException;
void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;
请求参数
名称 | 类型 | 描述 |
---|---|---|
serviceName | 字符串 | 服务名 |
ip | 字符串 | 服务实例IP |
port | int | 服务实例port |
clusterName | 字符串 | 集群名 |
返回参数
无
请求示例
NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
naming.deregisterInstance("nacos.test.3", "11.11.11.11", 8888, "DEFAULT");
获取全部实例
描述
获取服务下的所有实例。
List<Instance> getAllInstances(String serviceName) throws NacosException;
List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException;
请求参数
名称 | 类型 | 描述 |
---|---|---|
serviceName | 字符串 | 服务名 |
clusters | List | 集群列表 |
返回参数
List 实例列表。
请求示例
NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
System.out.println(naming.getAllInstances("nacos.test.3"));
获取健康或不健康实例列表
描述
根据条件获取过滤后的实例列表。
List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException;
List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) throws NacosException;
请求参数
名称 | 类型 | 描述 |
---|---|---|
serviceName | 字符串 | 服务名 |
clusters | List | 集群列表 |
healthy | boolean | 是否健康 |
返回参数
List 实例列表。
请求示例
NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
System.out.println(naming.selectInstances("nacos.test.3", true));
获取一个健康实例
描述
根据负载均衡算法随机获取一个健康实例。
Instance selectOneHealthyInstance(String serviceName) throws NacosException;
Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException;
请求参数
名称 | 类型 | 描述 |
---|---|---|
serviceName | 字符串 | 服务名 |
clusters | List | 集群列表 |
返回参数
Instance 实例。
请求示例
NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
System.out.println(naming.selectOneHealthyInstance("nacos.test.3"));
监听服务
描述
监听服务下的实例列表变化。
void subscribe(String serviceName, EventListener listener) throws NacosException;
void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;
请求参数
名称 | 类型 | 描述 |
---|---|---|
serviceName | 字符串 | 服务名 |
clusters | List | 集群列表 |
listener | EventListener | 回调listener |
返回参数
无
请求示例
NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
naming.subscribe("nacos.test.3", event -> {
if (event instanceof NamingEvent) {
System.out.println(((NamingEvent) event).getServceName());
System.out.println(((NamingEvent) event).getInstances());
}
});
取消监听服务
描述
取消监听服务下的实例列表变化。
void unsubscribe(String serviceName, EventListener listener) throws NacosException;
void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;
请求参数
名称 | 类型 | 描述 |
---|---|---|
serviceName | 字符串 | 服务名 |
clusters | List | 集群列表 |
listener | EventListener | 回调listener |
返回参数
无
请求示例
NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
naming.unsubscribe("nacos.test.3", event -> {});
其他语言的SDK
Nacos社区当前仅提供了Java版本的客户端,我们将主要依靠社区的贡献来发展多语言客户端。在未来,我们将向Nacos社区用户推荐那些最被广泛使用的以及支持最好的客户端作为Nacos相应语言的官方版本。
Open API 指南
-
配置管理
-
服务发现
-
命名空间
配置管理
获取配置
描述
获取Nacos上的配置。
请求类型
GET
请求URL
/nacos/v1/cs/configs
请求参数
名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|
tenant | string | 否 | 租户信息,对应 Nacos 的命名空间ID字段。 |
dataId | string | 是 | 配置 ID。 |
group | string | 是 | 配置分组。 |
返回参数
参数类型 | 描述 |
---|---|
string | 配置值 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例
-
请求示例
curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.example&group=com.alibaba.nacos'
-
返回示例
contentTest
监听配置
描述
监听 Nacos 上的配置,以便实时感知配置变更。如果配置变更,则用获取配置接口获取配置的最新值,动态刷新本地缓存。
注册监听采用的是异步 Servlet 技术。注册监听本质就是带着配置和配置值的 MD5 值和后台对比。如果 MD5 值不一致,就立即返回不一致的配置。如果值一致,就等待住 30 秒。返回值为空。
请求类型
POST
请求URL
/nacos/v1/cs/configs/listener
请求参数
名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|
Listening-Configs | string | 是 | 监听数据报文。格式为 dataId^2Group^2contentMD5^2tenant^1或者dataId^2Group^2contentMD5^1。dataId:配置 IDgroup:配置分组contentMD5:配置内容 MD5 值tenant:租户信息,对应 Nacos 的命名空间字段(非必填) |
Header 参数
名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|
Long-Pulling-Timeout | string | 是 | 长轮训等待 30s,此处填写 30000。 |
参数说明
-
配置多个字段间分隔符:^2 = Character.toString((char) 2
-
配置间分隔符:^1 = Character.toString((char) 1)
-
contentMD5: MD5(content),第一次本地缓存为空,所以这块为空串
返回参数
参数类型 | 描述 |
---|---|
string | 配置值 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例
-
请求示例
http://serverIp:8848/nacos/v1/cs/configs/listener
POST 请求体数据内容:
Listening-Configs=dataId^2group^2contentMD5^2tenant^1
-
返回示例
如果配置变化
dataId^2group^2tenant^1
如果配置无变化:会返回空串
发布配置
描述
发布 Nacos 上的配置。
请求类型
POST
请求 URL
/nacos/v1/cs/configs
请求参数
名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|
tenant | string | 否 | 租户信息,对应 Nacos 的命名空间ID字段 |
dataId | string | 是 | 配置 ID |
group | string | 是 | 配置分组 |
content | string | 是 | 配置内容 |
type | String | 否 | 配置类型 |
返回参数
参数类型 | 描述 |
---|---|
boolean | 是否发布成功 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例
-
请求示例
curl -X POST 'http://127.0.0.1:8848/nacos/v1/cs/configs' -d 'dataId=nacos.example&group=com.alibaba.nacos&content=contentTest'
-
返回示例
true
删除配置
描述
删除 Nacos 上的配置。
请求类型
DELETE
请求 URL
/nacos/v1/cs/configs
请求参数
名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|
tenant | string | 否 | 租户信息,对应 Naocs 的命名空间ID字段 |
dataId | string | 是 | 配置 ID |
group | string | 是 | 配置分组 |
返回参数
参数类型 | 描述 |
---|---|
boolean | 是否删除成功 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例
-
请求示例
curl -X DELETE 'http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.example&group=com.alibaba.nacos'
-
返回示例
true
查询历史版本
描述
查询配置项历史版本。
请求类型
GET
请求 URL
/nacos/v1/cs/history?search=accurate
请求参数
名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|
tenant | string | 否 | 租户信息,对应 Naocs 的命名空间ID字段 |
dataId | string | 是 | 配置 ID |
group | string | 是 | 配置分组 |
pageNo | integer | 否 | 当前页码 |
pageSize | integer | 否 | 分页条数(默认100条,最大为500) |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例
-
请求示例
curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/history?search=accurate&dataId=nacos.example&group=com.alibaba.nacos'
-
返回示例
{
"totalCount": 1,
"pageNumber": 1,
"pagesAvailable": 1,
"pageItems": [
{
"id": "203",
"lastId": -1,
"dataId": "nacos.example",
"group": "com.alibaba.nacos",
"tenant": "",
"appName": "",
"md5": null,
"content": null,
"srcIp": "0:0:0:0:0:0:0:1",
"srcUser": null,
"opType": "I ",
"createdTime": "2010-05-04T16:00:00.000+0000",
"lastModifiedTime": "2020-12-05T01:48:03.380+0000"
}
]
}
查询历史版本详情
描述
查询配置项历史版本详情
请求类型
GET
请求 URL
/nacos/v1/cs/history
请求参数
名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|
nid | Integer | 是 | 配置项历史版本ID |
tenant | string | 否 | 租户信息,对应 Naocs 的命名空间ID字段 (2.0.3起) |
dataId | string | 是 | 配置 ID (2.0.3起) |
group | string | 是 | 配置分组 (2.0.3起) |
注意:2.0.3版本起,此接口需要新增字段tenant、dataId和group,其中tenant非必填。
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例
-
请求示例
curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/history?nid=203&tenant=&dataId=nacos.example&group=com.alibaba.nacos'
-
返回示例
{
"id": "203",
"lastId": -1,
"dataId": "nacos.example",
"group": "com.alibaba.nacos",
"tenant": "",
"appName": "",
"md5": "9f67e6977b100e00cab385a75597db58",
"content": "contentTest",
"srcIp": "0:0:0:0:0:0:0:1",
"srcUser": null,
"opType": "I ",
"createdTime": "2010-05-04T16:00:00.000+0000",
"lastModifiedTime": "2020-12-05T01:48:03.380+0000"
}
查询配置上一版本信息
描述
查询配置上一版本信息(1.4起)
请求类型
GET
请求 URL
/nacos/v1/cs/history/previous
请求参数
名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|
id | Integer | 是 | 配置ID |
tenant | string | 否 | 租户信息,对应 Naocs 的命名空间ID字段 (2.0.3起) |
dataId | string | 是 | 配置 ID (2.0.3起) |
group | string | 是 | 配置分组 (2.0.3起) |
说明:2.0.3版本起,此接口需要新增字段tenant、dataId和group,其中tenant非必填。
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例
-
请求示例
curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/history/previous?id=309135486247505920&tenant=&dataId=nacos.example&group=com.alibaba.nacos'
-
返回示例
{
"id": "203",
"lastId": -1,
"dataId": "nacos.example",
"group": "com.alibaba.nacos",
"tenant": "",
"appName": "",
"md5": "9f67e6977b100e00cab385a75597db58",
"content": "contentTest",
"srcIp": "0:0:0:0:0:0:0:1",
"srcUser": null,
"opType": "I ",
"createdTime": "2010-05-04T16:00:00.000+0000",
"lastModifiedTime": "2020-12-05T01:48:03.380+0000"
}
服务发现
注册实例
描述
注册一个实例到服务。
请求类型
POST
请求路径
/nacos/v1/ns/instance
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
ip | 字符串 | 是 | 服务实例IP |
port | int | 是 | 服务实例port |
namespaceId | 字符串 | 否 | 命名空间ID |
weight | double | 否 | 权重 |
enabled | boolean | 否 | 是否上线 |
healthy | boolean | 否 | 是否健康 |
metadata | 字符串 | 否 | 扩展信息 |
clusterName | 字符串 | 否 | 集群名 |
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
ephemeral | boolean | 否 | 是否临时实例 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?port=8848&healthy=true&ip=11.11.11.11&weight=1.0&serviceName=nacos.test.3&encoding=GBK&namespaceId=n1'
示例返回
ok
注销实例
描述
删除服务下的一个实例。
请求类型
DELETE
请求路径
/nacos/v1/ns/instance
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
ip | 字符串 | 是 | 服务实例IP |
port | int | 是 | 服务实例port |
clusterName | 字符串 | 否 | 集群名称 |
namespaceId | 字符串 | 否 | 命名空间ID |
ephemeral | boolean | 否 | 是否临时实例 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X DELETE '127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.test.1&ip=1.1.1.1&port=8888&clusterName=TEST1'
示例返回
ok
修改实例
描述
修改服务下的一个实例。
注意:在Nacos2.0版本后,通过该接口更新的元数据拥有更高的优先级,且具有记忆能力;会在对应实例删除后,依旧存在一段时间,如果在此期间实例重新注册,该元数据依旧生效;您可以通过nacos.naming.clean.expired-metadata.expired-time
及nacos.naming.clean.expired-metadata.interval
对记忆时间进行修改
请求类型
PUT
请求路径
/nacos/v1/ns/instance
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
ip | 字符串 | 是 | 服务实例IP |
port | int | 是 | 服务实例port |
clusterName | 字符串 | 否 | 集群名称 |
namespaceId | 字符串 | 否 | 命名空间ID |
weight | double | 否 | 权重 |
metadata | JSON | 否 | 扩展信息 |
enabled | boolean | 否 | 是否打开流量 |
ephemeral | boolean | 否 | 是否临时实例 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X PUT '127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.test.1&ip=1.1.1.1&port=8888&clusterName=TEST1&weight=8&metadata={}'
示例返回
ok
查询实例列表
描述
查询服务下的实例列表
请求类型
GET
请求路径
/nacos/v1/ns/instance/list
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
clusters | 字符串,多个集群用逗号分隔 | 否 | 集群名称 |
healthyOnly | boolean | 否,默认为false | 是否只返回健康实例 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.test.1'
示例返回
{
"dom": "nacos.test.1",
"cacheMillis": 1000,
"useSpecifiedURL": false,
"hosts": [{
"valid": true,
"marked": false,
"instanceId": "10.10.10.10-8888-DEFAULT-nacos.test.1",
"port": 8888,
"ip": "10.10.10.10",
"weight": 1.0,
"metadata": {}
}],
"checksum": "3bbcf6dd1175203a8afdade0e77a27cd1528787794594",
"lastRefTime": 1528787794594,
"env": "",
"clusters": ""
}
查询实例详情
描述
查询一个服务下个某个实例详情。
请求类型
GET
请求路径
/nacos/v1/ns/instance
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
ip | 字符串 | 是 | 实例IP |
port | 字符串 | 是 | 实例端口 |
namespaceId | 字符串 | 否 | 命名空间ID |
cluster | 字符串 | 否 | 集群名称 |
healthyOnly | boolean | 否,默认为false | 是否只返回健康实例 |
ephemeral | boolean | 否 | 是否临时实例 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.test.2&ip=10.10.10.10&port=8888&cluster=DEFAULT'
示例返回
{
"metadata": {},
"instanceId": "10.10.10.10-8888-DEFAULT-nacos.test.2",
"port": 8888,
"service": "nacos.test.2",
"healthy": false,
"ip": "10.10.10.10",
"clusterName": "DEFAULT",
"weight": 1.0
}
发送实例心跳
描述
发送某个实例的心跳
请求类型
PUT
请求路径
/nacos/v1/ns/instance/beat
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
ephemeral | boolean | 否 | 是否临时实例 |
beat | JSON格式字符串 | 是 | 实例心跳内容 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X PUT '127.0.0.1:8848/nacos/v1/ns/instance/beat?serviceName=nacos.test.2&beat=%7b%22cluster%22%3a%22c1%22%2c%22ip%22%3a%22127.0.0.1%22%2c%22metadata%22%3a%7b%7d%2c%22port%22%3a8080%2c%22scheduled%22%3atrue%2c%22serviceName%22%3a%22jinhan0Fx4s.173TL.net%22%2c%22weight%22%3a1%7d'
示例返回
ok
创建服务
描述
创建一个服务
请求类型
POST
请求路径
/nacos/v1/ns/service
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
protectThreshold | 浮点数 | 否 | 保护阈值,取值0到1,默认0 |
metadata | 字符串 | 否 | 元数据 |
selector | JSON格式字符串 | 否 | 访问策略 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X POST '127.0.0.1:8848/nacos/v1/ns/service?serviceName=nacos.test.2&metadata=k1%3dv1'
示例返回
ok
删除服务
描述
删除一个服务,只有当服务下实例数为0时允许删除
请求类型
DELETE
请求路径
/nacos/v1/ns/service
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X DELETE '127.0.0.1:8848/nacos/v1/ns/service?serviceName=nacos.test.2'
示例返回
ok
修改服务
描述
更新一个服务
请求类型
PUT
请求路径
/nacos/v1/ns/service
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
protectThreshold | 浮点数 | 否 | 保护阈值,取值0到1,默认0 |
metadata | 字符串 | 否 | 元数据 |
selector | JSON格式字符串 | 否 | 访问策略 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X PUT '127.0.0.1:8848/nacos/v1/ns/service?serviceName=nacos.test.2&metadata=k1%3dv1'
示例返回
ok
查询服务
描述
查询一个服务
请求类型
GET
请求路径
/nacos/v1/ns/service
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/service?serviceName=nacos.test.2'
示例返回
{
metadata: { },
groupName: "DEFAULT_GROUP",
namespaceId: "public",
name: "nacos.test.2",
selector: {
type: "none"
},
protectThreshold: 0,
clusters: [
{
healthChecker: {
type: "TCP"
},
metadata: { },
name: "c1"
}
]
}
查询服务列表
描述
查询服务列表
请求类型
GET
请求路径
/nacos/v1/ns/service/list
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
pageNo | int | 是 | 当前页码 |
pageSize | int | 是 | 分页大小 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/service/list?pageNo=1&pageSize=2'
示例返回
{
"count":148,
"doms": [
"nacos.test.1",
"nacos.test.2"
]
}
查询系统开关
描述
查询系统开关
请求类型
GET
请求路径
/nacos/v1/ns/operator/switches
请求参数
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/operator/switches'
示例返回
{
name: "00-00---000-NACOS_SWITCH_DOMAIN-000---00-00",
masters: null,
adWeightMap: { },
defaultPushCacheMillis: 10000,
clientBeatInterval: 5000,
defaultCacheMillis: 3000,
distroThreshold: 0.7,
healthCheckEnabled: true,
distroEnabled: true,
enableStandalone: true,
pushEnabled: true,
checkTimes: 3,
httpHealthParams: {
max: 5000,
min: 500,
factor: 0.85
},
tcpHealthParams: {
max: 5000,
min: 1000,
factor: 0.75
},
mysqlHealthParams: {
max: 3000,
min: 2000,
factor: 0.65
},
incrementalList: [ ],
serverStatusSynchronizationPeriodMillis: 15000,
serviceStatusSynchronizationPeriodMillis: 5000,
disableAddIP: false,
sendBeatOnly: false,
limitedUrlMap: { },
distroServerExpiredMillis: 30000,
pushGoVersion: "0.1.0",
pushJavaVersion: "0.1.0",
pushPythonVersion: "0.4.3",
pushCVersion: "1.0.12",
enableAuthentication: false,
overriddenServerStatus: "UP",
defaultInstanceEphemeral: true,
healthCheckWhiteList: [ ],
checksum: null
}
修改系统开关
描述
修改系统开关
请求类型
PUT
请求路径
/nacos/v1/ns/operator/switches
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
entry | 字符串 | 是 | 开关名 |
value | 字符串 | 是 | 开关值 |
debug | boolean | 否 | 是否只在本机生效,true表示本机生效,false表示集群生效 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X PUT '127.0.0.1:8848/nacos/v1/ns/operator/switches?entry=pushEnabled&value=false&debug=true'
示例返回
ok
查看系统当前数据指标
描述
查看系统当前数据指标
请求类型
GET
请求路径
/nacos/v1/ns/operator/metrics
请求参数
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/operator/metrics'
示例返回
{
serviceCount: 336,
load: 0.09,
mem: 0.46210432,
responsibleServiceCount: 98,
instanceCount: 4,
cpu: 0.010242796,
status: "UP",
responsibleInstanceCount: 0
}
查看当前集群Server列表
描述
查看当前集群Server列表
请求类型
GET
请求路径
/nacos/v1/ns/operator/servers
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
healthy | boolean | 否 | 是否只返回健康Server节点 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/operator/servers'
示例返回
{
servers: [
{
ip: "1.1.1.1",
servePort: 8848,
site: "unknown",
weight: 1,
adWeight: 0,
alive: false,
lastRefTime: 0,
lastRefTimeStr: null,
key: "1.1.1.1:8848"
},
{
ip: "1.1.1.2",
servePort: 8848,
site: "unknown",
weight: 1,
adWeight: 0,
alive: false,
lastRefTime: 0,
lastRefTimeStr: null,
key: "1.1.1.2:8848"
},
{
ip: "1.1.1.3",
servePort: 8848,
site: "unknown",
weight: 1,
adWeight: 0,
alive: false,
lastRefTime: 0,
lastRefTimeStr: null,
key: "1.1.1.3:8848"
}
]
}
查看当前集群leader
描述
查看当前集群leader
请求类型
GET
请求路径
/nacos/v1/ns/raft/leader
请求参数
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/raft/leader'
示例返回
{
leader: "{"heartbeatDueMs":2500,"ip":"1.1.1.1:8848","leaderDueMs":12853,"state":"LEADER","term":54202,"voteFor":"1.1.1.1:8848"}"
}
更新实例的健康状态
描述
更新实例的健康状态,仅在集群的健康检查关闭时才生效,当集群配置了健康检查时,该接口会返回错误
请求类型
PUT
请求路径
/nacos/v1/ns/health/instance
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
namespaceId | 字符串 | 否 | 命名空间ID |
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
clusterName | 字符串 | 否 | 集群名 |
ip | 字符串 | 是 | 服务实例IP |
port | int | 是 | 服务实例port |
healthy | boolean | 是 | 是否健康 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X PUT 'http://127.0.0.1:8848/nacos/v1/ns/health/instance?port=8848&healthy=true&ip=11.11.11.11&serviceName=nacos.test.3&namespaceId=n1'
示例返回
ok
批量更新实例元数据(Beta)
描述
批量更新实例元数据(1.4起)
注意:该接口为Beta接口,后续版本可能有所修改,甚至删除,请谨慎使用。
请求类型
PUT
请求路径
/nacos/v1/ns/instance/metadata/batch
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
namespaceId | 字符串 | 是 | 命名空间ID |
serviceName | 字符串 | 是 | 服务名(group@@serviceName) |
consistencyType | 字符串 | 否 | 实例的类型(ephemeral/persist) |
instances | JSON格式字符串 | 否 | 需要更新的实例 |
metadata | JSON格式字符串 | 是 | 元数据信息 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
参数说明
-
consistencyType: 优先级高于instances参数,如果进行配置,则忽略instances参数的值。当值为'ephemeral',则对serviceName下的所有非持久化实例进行更新。当值为'persist',则对serviceName下的所有持久化实例进行更新。当为其他值,没有实例进行更新。
-
instances: json数组。通过ip+port+ephemeral+cluster定位到某一实例。
示例请求
curl -X PUT 'http://localhost:8848/nacos/v1/ns/instance/metadata/batch' -d 'namespaceId=public&serviceName=xxxx@@xxxx&instances=[{"ip":"3.3.3.3","port": "8080","ephemeral":"true","clusterName":"xxxx-cluster"},{"ip":"2.2.2.2","port":"8080","ephemeral":"true","clusterName":"xxxx-cluster"}]&metadata={"age":"20","name":"cocolan"}'
or
curl -X PUT 'http://localhost:8848/nacos/v1/ns/instance/metadata/batch' -d 'namespaceId=public&serviceName=xxxx@@xxxx&consistencyType=ephemeral&metadata={"age":"20","name":"cocolan"}'
示例返回
{"updated":["2.2.2.2:8080:unknown:xxxx-cluster:ephemeral","3.3.3.3:8080:unknown:xxxx-cluster:ephemeral"]}
批量删除实例元数据(Beta)
描述
批量删除实例元数据(1.4起)
注意:该接口为Beta接口,后续版本可能有所修改,甚至删除,请谨慎使用。
请求类型
DELETE
请求路径
/nacos/v1/ns/instance/metadata/batch
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
namespaceId | 字符串 | 是 | 命名空间ID |
serviceName | 字符串 | 是 | 服务名(group@@serviceName) |
consistencyType | 字符串 | 否 | 实例的类型(ephemeral/persist) |
instances | JSON格式字符串 | 否 | 需要更新的实例 |
metadata | JSON格式字符串 | 是 | 元数据信息 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
参数说明
-
consistencyType: 优先级高于instances参数,如果进行配置,则忽略instances参数的值。当值为ephemeral,则对serviceName下的所有非持久化实例进行更新。当值为persist,则对serviceName下的所有持久化实例进行更新。当为其他值,没有实例进行更新。
-
instances: json数组。通过ip+port+ephemeral+cluster定位到某一实例。
示例请求
curl -X DELETE 'http://localhost:8848/nacos/v1/ns/instance/metadata/batch' -d 'namespaceId=public&serviceName=xxxx@@xxxx&instances=[{"ip":"3.3.3.3","port": "8080","ephemeral":"true","clusterName":"xxxx-cluster"},{"ip":"2.2.2.2","port":"8080","ephemeral":"true","clusterName":"xxxx-cluster"}]&metadata={"age":"20","name":"cocolan"}'
or
curl -X DELETE 'http://localhost:8848/nacos/v1/ns/instance/metadata/batch' -d 'namespaceId=public&serviceName=xxxx@@xxxx&consistencyType=ephemeral&metadata={"age":"20","name":"cocolan"}'
示例返回
{"updated":["2.2.2.2:8080:unknown:xxxx-cluster:ephemeral","3.3.3.3:8080:unknown:xxxx-cluster:ephemeral"]}
命名空间
查询命名空间列表
请求类型
GET
请求路径
/nacos/v1/console/namespaces
请求参数
无
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X GET 'http://localhost:8848/nacos/v1/console/namespaces'
示例返回
{"code":200,"message":null,"data":[{"namespace":"","namespaceShowName":"public","quota":200,"configCount":0,"type":0}]}
创建命名空间
请求类型
POST
请求路径
/nacos/v1/console/namespaces
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
customNamespaceId | 字符串 | 是 | 命名空间ID |
namespaceName | 字符串 | 是 | 命名空间名 |
namespaceDesc | 字符串 | 否 | 命名空间描述 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X POST 'http://localhost:8848/nacos/v1/console/namespaces' -d 'customNamespaceId=&namespaceName=dev&namespaceDesc='
示例返回
true
修改命名空间
请求类型
PUT
请求路径
/nacos/v1/console/namespaces
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
namespaceId | 字符串 | 是 | 命名空间ID |
namespaceName | 字符串 | 是 | 命名空间名 |
namespaceDesc | 字符串 | 是 | 命名空间描述 |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X PUT 'http://localhost:8848/nacos/v1/console/namespaces' -d 'namespace=dev&namespaceShowName=开发环境2&namespaceDesc=只用于开发2'
示例返回
true
删除命名空间
请求类型
DELETE
请求路径
/nacos/v1/console/namespaces
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
namespaceId | 字符串 | 是 | 命名空间ID |
错误编码
错误代码 | 描述 | 语义 |
---|---|---|
400 | Bad Request | 客户端请求中的语法错误 |
403 | Forbidden | 没有权限 |
404 | Not Found | 无法找到资源 |
500 | Internal Server Error | 服务器内部错误 |
200 | OK | 正常 |
示例请求
curl -X DELETE 'http://localhost:8848/nacos/v1/console/namespaces' -d 'namespaceId=dev'
示例返回
true
Nacos Spring
本文将介绍 nacos-spring-context
中的一些关键的特性:
-
注解驱动
-
依赖注入
-
外部化配置
-
事件驱动
1. 注解驱动
1.1. 启用 Nacos
@EnableNacos
是一个模块驱动的注解,它支持 Nacos Spring 的所有功能,包括服务发现和配置管理。它等于 @EnableNacosDiscovery
加上 @EnableNacosConfig
,可以单独配置并在不同场景中使用。
1.2. 配置监听
假设在 Nacos 服务中有一个配置,其 dataId
是 "testDataId" 而 groupId
是默认组("DEFAULT_GROUP")。 现在,您可以使用 ConfigService#publishConfig
方法更改其内容:
private ConfigService configService;
public void testPublishConfig() throws NacosException {
configService.publishConfig(DATA_ID, DEFAULT_GROUP, "9527");
}
然后您可以添加一个监听器,它将监听配置的变化。 您可以通过在 Spring Bean 中添加配置变更监听器方法来执行此操作:
public void onMessage(String config) {
assertEquals("mercyblitz", config); // asserts true
}
下面的代码具有相同的效果:
configService.addListener(DATA_ID, DEFAULT_GROUP, new AbstractListener() {
public void receiveConfigInfo(String config) {
assertEquals("9527", config); // asserts true
}
});
另外,@NacosConfigListener
支持更丰富的类型转换。
1.2.1. 类型
@NacosConfigListener
的类型转换包括内置和自定义实现。 默认情况下,内置类型转换基于 Spring DefaultFormattingConversionService
,这意味着它包好了大多数情况以及 Spring 框架更高级版本的丰富功能。
例如,前面示例中的内容 "9527" 也可以通过带 "int" 或 "Integer" 参数的方法进行监听::
public void onInteger(Integer value) {
assertEquals(Integer.valueOf(9527), value); // asserts true
}
public void onInt(int value) {
assertEquals(9527, value); // asserts true
}
当然, nacos-spring-context
为开发人员提供弹性扩展。 如果定义名为nacosConfigConversionService
的Spring Bean,其类型为ConversionService
,则将忽略DefaultFormattingConversionService
。 此外,您可以自定义NacosConfigConverter
接口的实现,以指定类型转换的侦听器方法:
public class UserNacosConfigConverter implements NacosConfigConverter<User> {
public boolean canConvert(Class<User> targetType) {
return true;
}
public User convert(String source) {
return JSON.parseObject(source, User.class);
}
}
UserNacosConfigConverter
类绑定在 @NacosConfigListener.converter()
属性上,如下:
private ConfigService configService;
public void testPublishUser() throws NacosException {
configService.publishConfig("user", DEFAULT_GROUP, "{\"id\":1,\"name\":\"mercyblitz\"}");
}
public void onUser(User user) {
assertEquals(Long.valueOf(1L), user.getId());
assertEquals("mercyblitz", user.getName());
}
1.2.2. 超时时间
由于运行自定义的 NacosConfigConverter
可能需要一些时间,因此您可以在 @NacosConfigListener.timeout()
属性中设置最大执行时间,以防止它阻塞其他侦听器:
public class Listeners {
private Integer integerValue;
private Double doubleValue;
public void onInteger(Integer value) throws Exception {
Thread.sleep(100); // timeout of execution
this.integerValue = value;
}
public void onDouble(Double value) throws Exception {
Thread.sleep(100); // normal execution
this.doubleValue = value;
}
public Integer getIntegerValue() {
return integerValue;
}
public Double getDoubleValue() {
return doubleValue;
}
}
Listeners
Bean 的 integerValue
总是为null
,不会改变。 因此,以下断言都将是 true
:
private Listeners listeners;
public void testPublishConfig() throws NacosException {
configService.publishConfig(DATA_ID, DEFAULT_GROUP, "9527");
assertNull(listeners.getIntegerValue()); // asserts true
assertEquals(Double.valueOf(9527), listeners.getDoubleValue()); // asserts true
}
1.3. 全局和自定义 Nacos 属性
globalProperties
是任何 @EnableNacos
,@EnableNacosDiscovery
或 @EnableNacosConfig
中的必选属性,其类型为 @NacosProperties
。
globalProperties
将初始化为其他注解或组件的 "全局 Nacos 属性",例如:@NacosInjected
。
换句话说,全局 Nacos 属性 定义全局和默认属性。它设置为具有最低优先级,并且也可以被覆盖。覆盖优先级如下表所示:
Precedence Order | Nacos Annotation | Required |
---|---|---|
1 | *.properties() |
N |
2 | @EnableNacosConfig.globalProperties() or @EnableNacosDiscovery.globalProperties() |
Y |
3 | @EnableNacos.globalProperties() |
Y |
*.properties()
定义来自以下之一的自定义 Nacos 属性:
-
@NacosInjected.properties()
-
@NacosConfigListener.properties()
-
@NacosPropertySource.properties()
-
@NacosConfigurationProperties.properties()
自定义的 Nacos 属性也由 @NacosProperties
配置。 不过,它们是可选的,用于在特殊情况下覆盖全局 Nacos 属性。 如果没有定义,Nacos 属性将尝试从 @EnableNacosConfig.globalProperties()
或 @EnableNacosDiscovery.globalProperties()
或 @EnableNacos.globalProperties()
中查找属性。
1.4. @NacosProperties
@NacosProperties
是全局和自定义 Nacos 属性的统一注解。 它充当Java Properties
和 NacosFactory
类之间的中介。NacosFactory
负责创建 ConfigService
或 NamingService
实例。
@NacosProperties
的属性完全支持占位符,它的源是Spring Environment
抽象中的各种 PropertySource
,通常是Java System Properties
和操作系统环境变量。 所有占位符的前缀都是 nacos.
。@NacosProperties
和 Nacos 属性的属性之间的映射如下所示:
Attribute | Property | Placeholder | Description | Required |
---|---|---|---|---|
endpoint() |
endpoint |
${nacos.endpoint:} |
N | |
namespace() |
namespace |
${nacos.namespace:} |
N | |
accessKey() |
access-key |
${nacos.access-key:} |
N | |
secretKey() |
secret-key |
${nacos.secret-key:} |
N | |
serverAddr() |
server-addr |
${nacos.server-addr:} |
Y | |
contextPath() |
context-path |
${nacos.context-path:} |
N | |
clusterName() |
cluster-name |
${nacos.cluster-name:} |
N | |
encode() |
encode |
${nacos.encode:UTF-8} |
N |
请注意,@EnableNacosDiscovery
和 @EnableNacosConfig
之间 globalProperties()
的占位符存在一些差异:
Attribute | @EnableNacosDiscovery 's Placeholder | @EnableNacosConfig 's Placeholder |
---|---|---|
endpoint() |
${nacos.discovery.endpoint:${nacos.endpoint:}} |
${nacos.config.endpoint:${nacos.endpoint:}} |
namespace() |
${nacos.discovery.namespace:${nacos.namespace:}} |
${nacos.config.namespace:${nacos.namespace:}} |
accessKey() |
${nacos.discovery.access-key:${nacos.access-key:}} |
${nacos.config.access-key:${nacos.access-key:}} |
secretKey() |
${nacos.discovery.secret-key:${nacos.secret-key:}} |
${nacos.config.secret-key:${nacos.secret-key:}} |
serverAddr() |
${nacos.discovery.server-addr:${nacos.server-addr:}} |
${nacos.config.server-addr:${nacos.server-addr:}} |
contextPath() |
${nacos.discovery.context-path:${nacos.context-path:}} |
${nacos.config.context-path:${nacos.context-path:}} |
clusterName() |
${nacos.discovery.cluster-name:${nacos.cluster-name:}} |
${nacos.config.cluster-name:${nacos.cluster-name:}} |
encode() |
${nacos.discovery.encode:${nacos.encode:UTF-8}} |
${nacos.config.encode:${nacos.encode:UTF-8}} |
这些 @EnableNacosDiscovery
和 @EnableNacosConfig
的占位符用于隔离不同的 Nacos 服务,在大多数情况下都是不必要的。默认情况下,将使用常规占位符。
2. 依赖注入
@NacosInjected
是一个核心注解,用于在Spring Beans 中注入 ConfigService
或 NamingService
实例,并使这些实例可缓存。 这意味着如果它们的 @NacosProperties
相等,则实例将是相同的,无论属性是来自全局还是自定义的 Nacos 属性:
private ConfigService configService;
private ConfigService configService2;
private ConfigService configService3;
private NamingService namingService;
private NamingService namingService2;
private NamingService namingService3;
public void testInjection() {
Assert.assertEquals(configService, configService2);
Assert.assertNotEquals(configService2, configService3);
Assert.assertEquals(namingService, namingService2);
Assert.assertNotEquals(namingService2, namingService3);
}
属性 configService
使用 @EnableNacos#globalProperties()
或 @EnableNacosConfig#globalProperties()
,因为 encode
属性的默认值是 "UTF-8",因此 configService
实例和由 @NacosProperties(encode ="UTF-8")
注解的 configService2
实例是相同的。 namingService
和 namingService2
也是如此。
值得注意的是,与 NacosFactory.createConfigService()
方法创建的 ConfigService
实例不同,@NacosInjected
注解创建的 ConfigService
实例支持 Nacos Spring 事件。 例如,在增强的 ConfigService
调用 publishConfig()
方法之后会有一个 NacosConfigPublishedEvent
。 有关更多详细信息,请参阅"事件驱动"部分。
3. 外部化配置
外部化配置是 Spring Boot 引入的概念,它允许应用程序接收外部属性源以控制运行时行为。 Nacos Server 在应用程序外部运行单独的进程以维护应用程序配置。 nacos-spring-context
提供了对象绑定,动态配置(自动刷新)等功能。
这里有 nacos-spring-context
和 Spring Stack 之间的简单比较:
Spring Stack | Nacos Spring | Highlight |
---|---|---|
@Value |
@NacosValue |
auto-refreshed |
@ConfigurationProperties |
@NacosConfigurationProperties |
auto-refreshed,@NacosProperty ,@NacosIgnore |
@PropertySource |
@NacosPropertySource |
auto-refreshed, precedence order control |
@PropertySources |
@NacosPropertySources |
4. 事件驱动
Nacos 事件驱动 基于标准的 Spring Event / Listener 机制。 Spring 的 ApplicationEvent
是所有 Nacos Spring 事件的抽象超类:
Nacos Spring Event | Trigger |
---|---|
NacosConfigPublishedEvent |
After ConfigService.publishConfig() |
NacosConfigReceivedEvent |
AfterListener.receiveConfigInfo() |
NacosConfigRemovedEvent |
After configService.removeConfig() |
NacosConfigTimeoutEvent |
ConfigService.getConfig() on timeout |
NacosConfigListenerRegisteredEvent |
After ConfigService.addListner() or ConfigService.removeListener() |
NacosConfigurationPropertiesBeanBoundEvent |
After @NacosConfigurationProperties binding |
NacosConfigMetadataEvent |
After Nacos Config operations |
相关项目
Nacos 系统参数介绍
Nacos Server
对于Server端来说,一般是设置在{nacos.home}/conf/application.properties
里,如果参数名后标注了(-D)的,则表示是 JVM 的参数,需要在{nacos.home}/bin/startup.sh
里进行相应的设置。例如像设置 nacos.home 的值,可以在{nacos.home}/bin/startup.sh
进行如下设置:
JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"
全局参数
参数名 | 含义 | 可选值 | 默认值 | 支持版本 |
---|---|---|---|---|
nacos.home(-D) | Nacos的根目录 | 目录路径 | Nacos安装的目录 | >= 0.1.0 |
nacos.standalone(-D) | 是否在单机模式 | true/false | false | >= 0.1.0 |
nacos.functionMode(-D) | 启动模式,支持只启动某一个模块,不设置时所有模块都会启动 | config/naming/空 | 空 | >= 0.9.0 |
nacos.inetutils.prefer-hostname-over-ip | cluster.conf 里是否应该填hostname |
true/false | false | >= 0.3.0 |
nacos.inetutils.ip-address | 本机IP,该参数设置后,将会使用这个IP去cluster.conf 里进行匹配,请确保这个IP的值在cluster.conf 里是存在的 |
本机IP | null | >= 0.3.0 |
nacos.security.ignore.urls | 控制台鉴权跳过的接口 | 需要跳过控制台鉴权的接口列表 | 空 | >= 0.9.0 |
Naming模块
参数名 | 含义 | 可选值 | 默认值 | 支持版本 |
---|---|---|---|---|
nacos.naming.data.warmup | 是否在Server启动时进行数据预热 | true/false | false | >= 1.0.2 |
nacos.naming.expireInstance | 是否自动摘除临时实例 | true/false | true | >= 1.0.2 |
nacos.naming.distro.taskDispatchPeriod | 同步任务生成的周期,单位为毫秒 | 正整数 | 200 | >= 1.0.2 |
nacos.naming.distro.batchSyncKeyCount | 同步任务每批的key的数目 | 正整数 | 1000 | >= 1.0.2 |
nacos.naming.distro.syncRetryDelay | 同步任务失败的重试间隔,单位为毫秒 | 正整数 | 5000 | >= 1.0.2 |
除了上面列到的在application.properties
里配置的属性,还有一些可以在运行时调用接口来进行调节,这些参数都在Open API里的查看系统当前数据指标
这个API里有声明。
Config模块
参数名 | 含义 | 可选值 | 默认值 | 支持版本 |
---|---|---|---|---|
db.num | 数据库数目 | 正整数 | 0 | >= 0.1.0 |
db.url.0 | 第一个数据库的URL | 字符串 | 空 | >= 0.1.0 |
db.url.1 | 第二个数据库的URL | 字符串 | 空 | >= 0.1.0 |
db.user | 数据库连接的用户名 | 字符串 | 空 | >= 0.1.0 |
db.password | 数据库连接的密码 | 字符串 | 空 | >= 0.1.0 |
spring.datasource.platform | 数据库类型 | 字符串 | mysql | >=1.3.0 |
db.pool.config.xxx | 数据库连接池参数,使用的是hikari连接池,参数与hikari连接池相同,如db.pool.config.connectionTimeout 或db.pool.config.maximumPoolSize |
字符串 | 同hikariCp对应默认配置 | >=1.4.1 |
当前数据库配置支持多数据源。通过db.num
来指定数据源个数,db.url.index
为对应的数据库的链接。db.user
以及db.password
没有设置index
时,所有的链接都以db.user
和db.password
用作认证。如果不同数据源的用户名称或者用户密码不一样时,可以通过符号,
来进行切割,或者指定db.user.index
,db.user.password
来设置对应数据库链接的用户或者密码。需要注意的是,当db.user
和db.password
没有指定下标时,因为当前机制会根据,
进行切割。所以当用户名或者密码存在,
时,会把,
切割后前面的值当成最后的值进行认证,会导致认证失败。
Nacos从1.3版本开始使用HikariCP连接池,但在1.4.1版本前,连接池配置由系统默认值定义,无法自定义配置。在1.4.1后,提供了一个方法能够配置HikariCP连接池。 db.pool.config
为配置前缀,xxx
为实际的hikariCP配置,如db.pool.config.connectionTimeout
或db.pool.config.maximumPoolSize
等。更多hikariCP的配置请查看HikariCP 需要注意的是,url,user,password会由db.url.n
,db.user
,db.password
覆盖,driverClassName则是默认的MySQL8 driver(该版本mysql driver支持mysql5.x)
CMDB模块
参数名 | 含义 | 可选值 | 默认值 | 支持版本 |
---|---|---|---|---|
nacos.cmdb.loadDataAtStart | 是否打开CMDB | true/false | false | >= 0.7.0 |
nacos.cmdb.dumpTaskInterval | 全量dump的间隔,单位为秒 | 正整数 | 3600 | >= 0.7.0 |
nacos.cmdb.eventTaskInterval | 变更事件的拉取间隔,单位为秒 | 正整数 | 10 | >= 0.7.0 |
nacos.cmdb.labelTaskInterval | 标签集合的拉取间隔,单位为秒 | 正整数 | 300 | >= 0.7.0 |
Nacos Java Client
客户端的参数分为两种,一种是通过-D参数进行指定的配置,一种是构造客户端时,通过Properties
对象指定的配置,以下没有带-D标注的都是通过Properties
注入的配置。
通用参数
参数名 | 含义 | 可选值 | 默认值 | 支持版本 |
---|---|---|---|---|
endpoint | 连接Nacos Server指定的连接点,可以参考文档 | 域名 | 空 | >= 0.1.0 |
endpointPort | 连接Nacos Server指定的连接点端口,可以参考文档 | 合法端口号 | 空 | >= 0.1.0 |
namespace | 命名空间的ID | 命名空间的ID | config模块为空,naming模块为public | >= 0.8.0 |
serverAddr | Nacos Server的地址列表,这个值的优先级比endpoint高 | ip:port,ip:port,... | 空 | >= 0.1.0 |
JM.LOG.PATH(-D) | 客户端日志的目录 | 目录路径 | 用户根目录 | >= 0.1.0 |
Naming客户端
参数名 | 含义 | 可选值 | 默认值 | 支持版本 |
---|---|---|---|---|
namingLoadCacheAtStart | 启动时是否优先读取本地缓存 | true/false | false | >= 1.0.0 |
namingClientBeatThreadCount | 客户端心跳的线程池大小 | 正整数 | 机器的CPU数的一半 | >= 1.0.0 |
namingPollingThreadCount | 客户端定时轮询数据更新的线程池大小 | 正整数 | 机器的CPU数的一半 | >= 1.0.0 |
com.alibaba.nacos.naming.cache.dir(-D) | 客户端缓存目录 | 目录路径 | {user.home}/nacos/naming | >= 1.0.0 |
com.alibaba.nacos.naming.log.level(-D) | Naming客户端的日志级别 | info,error,warn等 | info | >= 1.0.0 |
com.alibaba.nacos.client.naming.tls.enable(-D) | 是否打开HTTPS | true/false | false | >= 1.0.0 |
Config客户端
参数名 | 含义 | 可选值 | 默认值 | 支持版本 |
---|---|---|---|---|
configLongPollTimeout(config.long-poll.timeout 1.0.1版本) | 长轮询的超时时间,单位为毫秒 | 正整数 | 30000 | >= 1.0.2 |
configRetryTime(config.retry.time 1.0.1版本) | 长轮询任务重试时间,单位为毫秒 | 正整数 | 2000 | >= 1.0.2 |
maxRetry | 长轮询的重试次数 | 正整数 | 3 | >= 1.0.2 |
enableRemoteSyncConfig | 监听器首次添加时拉取远端配置 | 布尔值 | false | >= 1.0.2 |
com.alibaba.nacos.config.log.level(-D) | Config客户端的日志级别 | info,error,warn等 | info | >= 1.0.0 |
JM.SNAPSHOT.PATH(-D) | 客户端缓存目录 | 目录路径 | {user.home}/nacos/config | >= 1.0.0 |
注意
Nacos是一个内部微服务组件,需要在可信的内部网络中运行,不可暴露在公网环境,防止带来安全风险。
Nacos提供简单的鉴权实现,为防止业务错用的弱鉴权体系,不是防止恶意攻击的强鉴权体系。
如果运行在不可信的网络环境或者有强鉴权诉求,请参考官方简单实现做替换增强。
鉴权
服务端如何开启鉴权
非Docker环境
按照官方文档配置启动,默认是不需要登录的,这样会导致配置中心对外直接暴露。而启用鉴权之后,需要在使用用户名和密码登录之后,才能正常使用nacos。
开启鉴权之前,application.properties中的配置信息为:
### If turn on auth system:
nacos.core.auth.enabled=false
开启鉴权之后,application.properties中的配置信息为:
### If turn on auth system:
nacos.core.auth.enabled=true
Docker环境
官方镜像
如果使用官方镜像,请在启动docker容器时,添加如下环境变量
NACOS_AUTH_ENABLE=true
例如,可以通过如下命令运行开启了鉴权的容器:
docker run --env PREFER_HOST_MODE=hostname --env MODE=standalone --env NACOS_AUTH_ENABLE=true -p 8848:8848 nacos/nacos-server
除此之外,还可以添加其他鉴权相关的环境变量信息:
name | description | option |
---|---|---|
NACOS_AUTH_ENABLE | 是否开启权限系统 | 默认:false |
NACOS_AUTH_TOKEN_EXPIRE_SECONDS | token 失效时间 | 默认:18000 |
NACOS_AUTH_TOKEN | token | 默认:SecretKey012345678901234567890123456789012345678901234567890123456789 |
NACOS_AUTH_CACHE_ENABLE | 权限缓存开关 ,开启后权限缓存的更新默认有15秒的延迟 | 默认 : false |
然后运行docker-compose构建命令,例如
docker-compose -f example/standalone-derby.yaml up
自定义镜像
如果选择自定义镜像,请在构建镜像之前,修改nacos工程中的application.properties文件,
将下面这一行配置信息
nacos.core.auth.enabled=false
修改为
nacos.core.auth.enabled=true
然后再配置nacos启动命令。
客户端如何进行鉴权
Java SDK鉴权
在构建“Properties”类时,需传入用户名和密码。
properties.put("username","${username}");
properties.put("password","${password}");
示例代码
try {
// Initialize the configuration service, and the console automatically obtains the following parameters through the sample code.
String serverAddr = "{serverAddr}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
// if need username and password to login
properties.put("username","nacos");
properties.put("password","nacos");
ConfigService configService = NacosFactory.createConfigService(properties);
} catch (NacosException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
其他语言的SDK鉴权
待补充
Open-API鉴权
首先需要使用用户名和密码登陆nacos。
curl -X POST '127.0.0.1:8848/nacos/v1/auth/login' -d 'username=nacos&password=nacos'
若用户名和密码正确,返回信息如下:
{"accessToken":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTYwNTYyOTE2Nn0.2TogGhhr11_vLEjqKko1HJHUJEmsPuCxkur-CfNojDo","tokenTtl":18000,"globalAdmin":true}
接下来进行配置信息或服务信息时,应当使用该accessToken鉴权,在url后添加参数accessToken={accessToken},其中{accessToken}为登录时返回的token信息,例如
curl -X GET '127.0.0.1:8848/nacos/v1/cs/configs?accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTYwNTYyMzkyM30.O-s2yWfDSUZ7Svd3Vs7jy9tsfDNHs1SuebJB4KlNY8Q&dataId=nacos.example.1&group=nacos_group'
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTYwNTYyMzkyM30.O-s2yWfDSUZ7Svd3Vs7jy9tsfDNHs1SuebJB4KlNY8Q&port=8848&healthy=true&ip=11.11.11.11&weight=1.0&serviceName=nacos.test.3&encoding=GBK&namespaceId=n1'
开启服务身份识别功能
开启鉴权功能后,服务端之间的请求也会通过鉴权系统的影响。考虑到服务端之间的通信应该是可信的,因此在1.2~1.4.0版本期间,通过User-Agent中是否包含Nacos-Server来进行判断请求是否来自其他服务端。
但这种实现由于过于简单且固定,导致可能存在安全问题。因此从1.4.1版本开始,Nacos添加服务身份识别功能,用户可以自行配置服务端的Identity,不再使用User-Agent作为服务端请求的判断标准。
开启方式:
### 开启鉴权
nacos.core.auth.enabled=true
### 关闭使用user-agent判断服务端请求并放行鉴权的功能
nacos.core.auth.enable.userAgentAuthWhite=false
### 配置自定义身份识别的key(不可为空)和value(不可为空)
nacos.core.auth.server.identity.key=example
nacos.core.auth.server.identity.value=example
** 注意 ** 所有集群均需要配置相同的server.identity
信息,否则可能导致服务端之间数据不一致或无法删除实例等问题。
旧版本升级
考虑到旧版本用户需要升级,可以在升级期间,开启nacos.core.auth.enable.userAgentAuthWhite=true
功能,待集群整体升级到1.4.1并稳定运行后,再关闭此功能。
FAQ
-
Nacos常规问题
-
Nacos运维问题
-
Nacos使用问题
-
Nacos原理问题
Nacos常规问题
Nacos是什么
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。详情可以参考Nacos官网介绍。
Nacos如何支持多环境
在日常使用中常常需要不同的环境,比如日常,预发,线上环境,如果是逻辑隔离可以使用命名空间,Nacos支持命名空间来支持多环境隔离,可以在Nacos控制台创建多个命名空间。如果需要物理隔离,就要部署多套Nacos环境。
Nacos是否生产可用
Nacos在2019.1发布了Pre-GA版本,支持了安全隔离、监控和服务迁移等上生产的最后一公里,以更稳定的支撑用户的生产环境。详情可以参考Nacos 发布 v0.8.0 Pre-GA 版本,安全稳定上生产。
Nacos版本计划
Nacos 0.8.0 开始支持生产可用,1.0版本达到大规模生产可用,2.0版本计划与K8s、Spring Cloud、Service Mesh、Serverless进一步融合,具体的详情参考Nacos规划。
Nacos有什么依赖
在单机模式下,Nacos没有任何依赖,在集群模式下,Nacos依赖Mysql做存储,详情可以参考Nacos部署。
Nacos使用什么开源协议
Nacos使用Apache 2.0。
Nacos运维问题
Nacos如何单机部署
可以参考Nacos官网部署手册quick start。
Nacos单机部署如何使用mysql
Nacos单机模式默认使用内嵌的数据库作为存储引擎,如果想换成自己安装的mysql,可以按照官网文档。
生产环境如何部署Nacos
生产环境使用Nacos为了达到高可用不能使用单机模式,需要搭建nacos集群,具体详情可以参考集群部署手册。
Nacos如何Docker部署
除了使用压缩包部署Nacos,Nacos也提供了相应的Docker镜像,当Nacos发布新的版本的时候,Nacos会发布对应的镜像版本支持Docker部署。具体详情可以参考Nacos Docker。
如何在k8s中部署Nacos
在生产环境部署Nacos集群,如果要对Nacos进行扩容操作,需要手动更改集群ip文件,启动新的Nacos服务。为了能进行自动化运维,Nacos和k8s结合利用StatefulSets提供了自动运维方案,能对Nacos进行动态扩缩容,具体详情参考Kubernetes Nacos。
如何监控Nacos
Nacos0.8版本提供了Metrics数据暴露能力,能通过Metrics数据的内容对Nacos的运行状态进行监控,详情参考Nacos监控。
Nacos在Docker环境下集群部署,无法正常启动,日志一直打印 Nacos is starting...
原因可能是由于Docker环境下,内存不足导致另外的服务无法正常启动,最后导致服务报错,一直重启,可以通过增大Docker限制内存尝试解决。
Nacos使用问题
Zookeeper上的服务可以迁移到Nacos上吗
可以通过Nacos-Sync把Zookeeper服务迁移到Nacos,也可以从Nacos迁移到Zookeeper,具体可以参考Nacos Sync 使用。
Nacos支持多配置文件
Nacos通过Spring Cloud Alibaba Nacos Config支持了多配置文件,可以将配置存储在多个独立的配置文件中。关联的issue,详情参考文档Spring Cloud Alibaba Nacos Config。
Nacos支持Dubbo
Nacos 0.6版本和Dubbo集成,支持使用Nacos作为注册中心,关联issue,具体文档参考Dubbo 融合 Nacos 成为注册中心。
Nacos支持Spring体系
Nacos完善支持了Sping技术栈,具体可以参考Nacos Spring、Nacos Spring Boot、Spring Cloud。
不使用Nacos SDK如何访问Nacos
Nacos的网络交互都是基于Http协议实现的,提供了Open-API可以很容易实现Nacos的访问。
Nacos对多语言的支持
Nacos目前只支持Java,对于其他语言的支持还正在开发中,需要大家大力支持一起共建。
Nacos0.8版本登陆失败
Nacos 0.8版本当使用openjdk并且没有JAVA_HOME
的环境变量时,nacos可以启动成功,是因为yum install
安装的openjdk 会把java命令注册一份到/bin
目录下面,所以会引发SignatureException
异常。这个问题已经修复,0.9版本会发版,具体详情可以参考issue。
服务端报错 java.lang.IllegalStateException: unable to find local peer: 127.0.0.1:8848
这个问题是因为Nacos获取本机IP时,没有获取到正确的外部IP.需要保证InetAddress.getLocalHost().getHostAddress()
或者hostname -i
的结果是与cluster.conf里配置的IP是一致的。
Nacos如何对配置进行加密
Nacos计划在1.X版本提供加密的能力,目前还不支持加密,只能靠sdk做好了加密再存到nacos中。
Nacos报401错误
Nacos服务端报错了,可以检查服务端日志,参考issue。
Nacos权重不生效
Nacos控制台上编辑权重, 目前从SpringCloud客户端和Dubbo客户端都没有打通, 所以不能生效. 对于SpringCloud客户端, 应用可以实现Ribbon的负载均衡器来进行权重过滤。
Nacos如何扩缩容
目前支持修改cluster.conf文件的方式进行扩缩容, 改完后无需重启, Server会自动刷新到文件新内容。
Nacos客户端修改日志级别
配置-D参数com.alibaba.nacos.naming.log.level设置naming客户端的日志级别,例如设置为error: -Dcom.alibaba.nacos.naming.log.level=error
同样的,-D参数com.alibaba.nacos.config.log.level用来设置config客户端的日志级别。
Nacos与Zipkin 整合出现 Service not found 问题
配置spring-cloud-seluth
参数:spring.zipkin.discovery-client-enabled=false
。
如果仍然存在Service not found
错误,则建议先使用open-api将Zipkin-server注册为永久实例服务:
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?port=9411&healthy=true&ip=127.0.0.1&weight=1.0&serviceName=zipkin-server&ephemeral=false&namespaceId=public'
然后,前往nacos控制台,找到服务名为zipkin-server
的服务,找到集群配置,设置健康检查模式为TCP
,端口号为9411
(即zipkin-server的端口)。
如何依赖最新的Nacos客户端?
很多用户都是通过Spring Cloud Alibaba或者Dubbo依赖的Nacos客户端,那么Spring Cloud Alibaba和Dubbo中依赖的Nacos客户端版本,往往会落后于Nacos最新发布的版本。在一些情况下,用户需要强制将Nacos客户端升级到最新,此时却往往不知道该升级哪个依赖,这里将Spring Cloud Alibaba和Dubbo的依赖升级说明如下:
Spring Cloud Alibaba
用户通常是配置以下Maven依赖来使用的Nacos:
<!--Nacos Discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>[latest version]</version>
</dependency>
<!--Nacos Config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>[latest version]</version>
</dependency>
这两个jar包实际上又依赖了以下的jar包:
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>[a particular version]</version>
</dependency>
如果nacos-client升级了,对应的spring-cloud客户端版本不一定也同步升级,这个时候可以采用如下的方式强制升级nacos-client(以nacos-discovery为例):
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>[latest version]</version>
<excludes>
<exclude>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclude>
</excludes>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>[latest version]</version>
</dependency>
Dubbo
Dubbo也是类似的道理,用户通常引入的是以下的依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>[latest version]</version>
</dependency>
<!-- Dubbo dependency -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>[latest version]</version>
</dependency>
需要升级Nacos客户端时,只需要如下修改依赖:
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>[latest version]</version>
</dependency>
客户端CPU高,或者内存耗尽的问题
问题的现象是依赖Nacos客户端的应用,在运行一段时间后出现CPU占用率高,内存占用高甚至内存溢出的现象,可以参考issue:https://github.com/alibaba/nacos/issues/1605。这种情况首先要做的是分析CPU高或者内存占用高的原因,常用的命令有top、jstack、jmap、jhat等。其中一种情况是Nacos客户端实例在Spring Cloud Alibaba服务框架中被反复构造了多次,可以参考issue:https://github.com/alibaba/spring-cloud-alibaba/issues/859。这个问题已经得到了修复,预期会在下个Spring Cloud Alibaba版本中发布。
日志打印频繁的问题
在老的Nacos版本中,往往会有大量的无效日志打印,这些日志的打印会迅速占用完用户的磁盘空间,同时也让有效日志难以查找。目前社区反馈的日志频繁打印主要有以下几种情况:
-
access日志大量打印,相关issue有:https://github.com/alibaba/nacos/issues/1510。主要表现是{nacos.home}/logs/access_log.2019-xx-xx.log类似格式文件名的日志大量打印,而且还不能自动清理和滚动。这个日志是Spring Boot提供的tomcat访问日志打印,Spring Boot在关于该日志的选项中,没有最大保留天数或者日志大小控制的选项。因此这个日志的清理必须由应用新建crontab任务来完成,或者通过以下命令关闭日志的输出(在生产环境我们还是建议开启该日志,以便能够有第一现场的访问记录):
server.tomcat.accesslog.enabled=false
-
服务端业务日志大量打印且无法动态调整日志级别。这个问题在1.1.3已经得到优化,可以通过API的方式来进行日志级别的调整,调整日志级别的方式如下:
# 调整naming模块的naming-raft.log的级别为error:
curl -X PUT '$nacos_server:8848/nacos/v1/ns/operator/log?logName=naming-raft&logLevel=error'
# 调整config模块的config-dump.log的级别为warn:
curl -X PUT '$nacos_server:8848/nacos/v1/cs/ops/log?logName=config-dump&logLevel=warn'
-
客户端日志大量打印,主要有心跳日志、轮询日志等。这个问题已经在1.1.3解决,请升级到1.1.3版本。
集群管理页面,raft term显示不一致问题
在Nacos 1.0.1版本中,Nacos控制台支持了显示当前的集群各个机器的状态信息。这个功能受到比较多用户的关注,其中一个被反馈的问题是列表中每个节点的集群任期不一样。如下图所示(图片信息来自issue:https://github.com/alibaba/nacos/issues/1786):
对于这个任期不一致的问题,原因主要是因为获取这个信息的逻辑有一些问题,没有从对应的节点上获取集群任期。这个问题会在下一个Nacos版本中修复。目前一个手动检查集群任期的办法是在每个节点上执行以下命令:
curl '127.0.0.1:8848/nacos/v1/ns/raft/state'
然后在返回信息中查找本节点的集群任期。因为每个节点返回的集群任期中,只有当前节点的信息是准确的,返回的其他节点的信息都是不准确的。
找不到符号com.alibaba.nacos.consistency.entity
这个包目录是由protobuf
在编译时自动生成,您可以通过mvn compile
来自动生成他们。如果您使用的是IDEA,也可以使用IDEA的protobuf插件。
Nacos原理问题
Nacos部署环境
Nacos定义为一个IDC内部应用组件,并非面向公网环境的产品,建议在内部隔离网络环境中部署,强烈不建议部署在公共网络环境。
以下文档中提及的VIP,网卡等所有网络相关概念均处于内部网络环境。
Nacos支持三种部署模式
-
单机模式 - 用于测试和单机试用。
-
集群模式 - 用于生产环境,确保高可用。
-
多集群模式 - 用于多数据中心场景。
单机模式下运行Nacos
Linux/Unix/Mac
-
Standalone means it is non-cluster Mode. * sh startup.sh -m standalone
Windows
-
Standalone means it is non-cluster Mode. * cmd startup.cmd -m standalone
单机模式支持mysql
在0.7版本之前,在单机模式时nacos使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况。0.7版本增加了支持mysql数据源能力,具体的操作步骤:
-
1.安装数据库,版本要求:5.6.5+
-
2.初始化mysql数据库,数据库初始化文件:nacos-mysql.sql
-
3.修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=youdontknow
再以单机模式启动nacos,nacos所有写嵌入式数据库的数据都写到了mysql
集群模式下运行Nacos
多集群模式
Nacos支持NameServer路由请求模式,通过它您可以设计一个有用的映射规则来控制请求转发到相应的集群,在映射规则中您可以按命名空间或租户等分片请求...
多网卡IP选择
当本地环境比较复杂的时候,Nacos服务在启动的时候需要选择运行时使用的IP或者网卡。Nacos从多网卡获取IP参考Spring Cloud设计,通过nacos.inetutils参数,可以指定Nacos使用的网卡和IP地址。目前支持的配置参数有:
-
ip-address参数可以直接设置nacos的ip
nacos.inetutils.ip-address=10.11.105.155
-
use-only-site-local-interfaces参数可以让nacos使用局域网ip,这个在nacos部署的机器有多网卡时很有用,可以让nacos选择局域网网卡
nacos.inetutils.use-only-site-local-interfaces=true
-
ignored-interfaces支持网卡数组,可以让nacos忽略多个网卡
nacos.inetutils.ignored-interfaces[0]=eth0
nacos.inetutils.ignored-interfaces[1]=eth1
-
preferred-networks参数可以让nacos优先选择匹配的ip,支持正则匹配和前缀匹配
nacos.inetutils.preferred-networks[0]=30.5.124.
nacos.inetutils.preferred-networks[0]=30.5.124.(25[0-5]|2[0-4]\\d|((1d{2})|([1-9]?\\d))),30.5.124.(25[0-5]|2[0-4]\\d|((1d{2})|([1-9]?\\d)))
集群部署说明
集群模式部署
这个快速开始手册是帮忙您快速在你的电脑上,下载安装并使用Nacos,部署生产使用的集群模式。
集群部署架构图
因此开源的时候推荐用户把所有服务列表放到一个vip下面,然后挂到一个域名下面
http://ip1:port/openAPI 直连ip模式,机器挂则需要修改ip才可以使用。
http://SLB:port/openAPI 挂载SLB模式(内网SLB,不可暴露到公网,以免带来安全风险),直连SLB即可,下面挂server真实ip,可读性不好。
http://nacos.com:port/openAPI 域名 + SLB模式(内网SLB,不可暴露到公网,以免带来安全风险),可读性好,而且换ip方便,推荐模式
1. 预备环境准备
请确保是在环境中安装使用:
-
64 bit OS Linux/Unix/Mac,推荐使用Linux系统。
-
3个或3个以上Nacos节点才能构成集群。
2. 下载源码或者安装包
你可以通过两种方式来获取 Nacos。
从 Github 上下载源码方式
unzip nacos-source.zip
cd nacos/
mvn -Prelease-nacos clean install -U
cd nacos/distribution/target/nacos-server-1.3.0/nacos/bin
下载编译后压缩包方式
下载地址
unzip nacos-server-1.3.0.zip 或者 tar -xvf nacos-server-1.3.0.tar.gz
cd nacos/bin
3. 配置集群配置文件
在nacos的解压目录nacos/的conf目录下,有配置文件cluster.conf,请每行配置成ip:port。(请配置3个或3个以上节点)
# ip:port
200.8.9.16:8848
200.8.9.17:8848
200.8.9.18:8848
4. 确定数据源
使用内置数据源
无需进行任何配置
使用外置数据源
生产使用建议至少主备模式,或者采用高可用数据库。
初始化 MySQL 数据库
application.properties 配置
5. 启动服务器
Linux/Unix/Mac
Stand-alone mode
sh startup.sh -m standalone
集群模式
使用内置数据源
sh startup.sh -p embedded
使用外置数据源
sh startup.sh
6. 服务注册&发现和配置管理
服务注册
curl -X PUT 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'
服务发现
curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'
发布配置
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"
7. 关闭服务器
Linux/Unix/Mac
sh shutdown.sh
IN PLAN with Nacos 1.x.x
控制台手册
Nacos 控制台主要旨在于增强对于服务列表,健康状态管理,服务治理,分布式配置管理等方面的管控能力,以便进一步帮助用户降低管理微服务应用架构的成本,将提供包括下列基本功能:
-
服务管理
-
服务列表及服务健康状态展示
-
服务元数据存储及编辑
-
服务流量权重的调整
-
服务优雅上下线
-
-
配置管理
-
多种配置格式编辑
-
编辑DIFF
-
示例代码
-
推送状态查询
-
配置版本及一键回滚
-
-
命名空间
-
登录管理
特性详解
服务管理
开发者或者运维人员往往需要在服务注册后,通过友好的界面来查看服务的注册情况,包括当前系统注册的所有服务和每个服务的详情。并在有权限控制的情况下,进行服务的一些配置的编辑操作。Nacos在这个版本开放的控制台的服务发现部分,主要就是提供用户一个基本的运维页面,能够查看、编辑当前注册的服务。
服务列表管理
服务列表帮助用户以统一的视图管理其所有的微服务以及服务健康状态。整体界面布局是左上角有服务的搜索框和搜索按钮,页面中央是服务列表的展示。服务列表主要展示服务名、集群数目、实例数目、健康实例数目和详情按钮五个栏目。
在服务列表页面点击详情,可以看到服务的详情。可以查看服务、集群和实例的基本信息。
服务流量权重支持及流量保护
Nacos 为用户提供了流量权重控制的能力,同时开放了服务流量的阈值保护,以帮助用户更好的保护服务服务提供者集群不被意外打垮。如下图所以,可以点击实例的编辑按钮,修改实例的权重。如果想增加实例的流量,可以将权重调大,如果不想实例接收流量,则可以将权重设为0。
服务元数据管理
Nacos提供多个维度的服务元数据的暴露,帮助用户存储自定义的信息。这些信息都是以K-V的数据结构存储,在控制台上,会以k1=v1,k2=v2这样的格式展示。类似的,编辑元数据可以通过相同的格式进行。例如服务的元数据编辑,首先点击服务详情页右上角的“编辑服务”按钮,然后在元数据输入框输入:version=1.0,env=prod。
点击确认,就可以在服务详情页面,看到服务的元数据已经更新了。
服务优雅上下线
Nacos还提供服务实例的上下线操作,在服务详情页面,可以点击实例的“上线”或者“下线”按钮,被下线的实例,将不会包含在健康的实例列表里。
配置管理
Nacos支持基于Namespace和Group的配置分组管理,以便用户更灵活的根据自己的需要按照环境或者应用、模块等分组管理微服务以及Spring的大量配置,在配置管理中主要提供了配置历史版本、回滚、订阅者查询等核心管理能力。
多配置格式编辑器
Nacos支持 YAML、Properties、TEXT、JSON、XML、HTML 等常见配置格式在线编辑、语法高亮、格式校验,帮助用户高效编辑的同时大幅降低格式错误带来的风险。
Nacos支持配置标签的能力,帮助用户更好、更灵活的做到基于标签的配置分类及管理。同时支持用户对配置及其变更进行描述,方面多人或者跨团队协作管理配置。
编辑DIFF
Nacos支持编辑DIFF能力,帮助用户校验修改内容,降低改错带来的风险。
示例代码
Nacos提供示例代码能力,能够让新手快速使用客户端编程消费该配置,大幅降低新手使用门槛。
监听者查询
Nacos提供配置订阅者即监听者查询能力,同时提供客户端当前配置的MD5校验值,以便帮助用户更好的检查配置变更是否推送到 Client 端。
配置的版本及一键回滚
Nacos通过提供配置版本管理及其一键回滚能力,帮助用户改错配置的时候能够快速恢复,降低微服务系统在配置管理上的一定会遇到的可用性风险。
命名空间管理
Nacos 基于Namespace 帮助用户逻辑隔离多个命名空间,这可以帮助用户更好的管理测试、预发、生产等多环境服务和配置,让每个环境的同一个配置(如数据库数据源)可以定义不同的值。
登录管理
Nacos0.8 版本支持简单登录功能,默认用户名/密码为: nacos/nacos
。
修改默认用户名/密码方法
-
生成加密密码, 在
com.alibaba.nacos.console.utils.PasswordEncoderUtil.main
函数中,将 nacos 改成你要改成的密码,运行即可得到加密有算法。注意盐值是随机的,所以生成密码每次可能不一样,请不要担心。
public class PasswordEncoderUtil {
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("nacos"));
}
}
-
创建用户名或者密码的时候,用指定用户名密码即可。
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
关闭登录功能
由于部分公司自己开发控制台,不希望被nacos的安全filter拦截。因此nacos支持定制关闭登录功能找到配置文件 ${nacoshome}/conf/application.properties
, 替换以下内容即可。
## spring security config
### turn off security
spring.security.enabled=false
management.security=false
security.basic.enabled=false
nacos.security.ignore.urls=/**
#nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**
会话时间
默认会话保持时间为30分钟。30分钟后需要重新登录认证。 暂时不支持修改该默认时间。
社区参与的前端共建
在Nacos前端风格、布局的讨论中,社区踊跃投票,最终选择了这套经典黑白蓝风格的皮肤,并且通过我们UED程瑶同学的设计,布局,让交互变得十分自然流畅。
在控制台的开发之前,我们通过社区招募到了很多前端同学一起参与了前端代码的开发,在此尤其感谢李晨、王庆、王彦民同学在Nacos前端开发过程中的大力支持!
坚持社区化发展,欢迎加入并贡献社区
比吐槽更重要的是搭把手,参与社区一起发展Nacos!
要加入Nacos 微信社区讨论 Nacos 产品的演进,你可以通过扫超哥的微信二维码,让“超哥” 帮你拉入 “Nacos社区交流群”。
更多与 Nacos 相关的开源项目信息:
Nacos 监控手册
Nacos 0.8.0版本完善了监控系统,支持通过暴露metrics数据接入第三方监控系统监控Nacos运行状态,目前支持prometheus、elastic search和influxdb,下面结合prometheus和grafana如何监控Nacos,官网grafana监控页面。与elastic search和influxdb结合可自己查找相关资料
搭建Nacos集群暴露metrics数据
按照部署文档搭建好Nacos集群
配置application.properties文件,暴露metrics数据
management.endpoints.web.exposure.include=*
访问{ip}:8848/nacos/actuator/prometheus,看是否能访问到metrics数据
搭建prometheus采集Nacos metrics数据
下载你想安装的prometheus版本,地址为download prometheus
linux & mac
解压prometheus压缩包
tar xvfz prometheus-*.tar.gz
cd prometheus-*
修改配置文件prometheus.yml采集Nacos metrics数据
metrics_path
static_configs
启动prometheus服务
./prometheus --config.file="prometheus.yml"
windows
下载对应的windows版本并解压
修改配置文件prometheus.yml采集Nacos metrics数据
metrics_path: '/nacos/actuator/prometheus'
static_configs:
- targets: ['{ip1}:8848','{ip2}:8848','{ip3}:8848']
启动prometheus服务
prometheus.exe --config.file=prometheus.yml
通过访问http://{ip}:9090/graph可以看到prometheus的采集数据,在搜索栏搜索nacos_monitor可以搜索到Nacos数据说明采集数据成功
搭建grafana图形化展示metrics数据
和prometheus在同一台机器上安装grafana,使用 yum 安装grafana
mac
brew install grafana
brew services start grafana
linux
sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.2.4-1.x86_64.rpm
sudo service grafana-server start
windows
参考文档:http://docs.grafana.org/installation/windows/
访问grafana: http://{ip}:3000
配置prometheus数据源
导入Nacos grafana监控模版
Nacos监控分为三个模块:
-
nacos monitor展示核心监控项
-
nacos detail展示指标的变化曲线
-
nacos alert为告警项
配置grafana告警
当Nacos运行出现问题时,需要grafana告警通知相关负责人。grafana支持多种告警方式,常用的有邮件,钉钉和webhook方式
钉钉告警
钉钉可以通过配置钉钉机器人
配置钉钉通知url
测试告警项
邮件告警
修改defaults.ini配置文件,增加邮件告警
#################################### SMTP / Emailing ##########################
[smtp]
enabled = true
host = smtp.126.com:25
user = xxxxxx
password = xxxxx
;cert_file =
;key_file =
skip_verify = true
from_address = xxxxxx@126.com
[emails]
;welcome_email_on_sign_up = false
配置通知邮箱
Nacos metrics含义
jvm metrics
指标 | 含义 |
---|---|
system_cpu_usage | CPU使用率 |
system_load_average_1m | load |
jvm_memory_used_bytes | 内存使用字节,包含各种内存区 |
jvm_memory_max_bytes | 内存最大字节,包含各种内存区 |
jvm_gc_pause_seconds_count | gc次数,包含各种gc |
jvm_gc_pause_seconds_sum | gc耗时,包含各种gc |
jvm_threads_daemon | 线程数 |
Nacos 监控指标
指标 | 含义 |
---|---|
http_server_requests_seconds_count | http请求次数,包括多种(url,方法,code) |
http_server_requests_seconds_sum | http请求总耗时,包括多种(url,方法,code) |
nacos_timer_seconds_sum | Nacos config水平通知耗时 |
nacos_timer_seconds_count | Nacos config水平通知次数 |
nacos_monitor{name='longPolling'} | Nacos config长连接数 |
nacos_monitor{name='configCount'} | Nacos config配置个数 |
nacos_monitor{name='dumpTask'} | Nacos config配置落盘任务堆积数 |
nacos_monitor{name='notifyTask'} | Nacos config配置水平通知任务堆积数 |
nacos_monitor{name='getConfig'} | Nacos config读配置统计数 |
nacos_monitor{name='publish'} | Nacos config写配置统计数 |
nacos_monitor{name='ipCount'} | Nacos naming ip个数 |
nacos_monitor{name='domCount'} | Nacos naming域名个数 |
nacos_monitor{name='failedPush'} | Nacos naming推送失败数 |
nacos_monitor{name='avgPushCost'} | Nacos naming平均推送耗时 |
nacos_monitor{name='leaderStatus'} | Nacos naming角色状态 |
nacos_monitor{name='maxPushCost'} | Nacos naming最大推送耗时 |
nacos_monitor{name='mysqlhealthCheck'} | Nacos naming mysql健康检查次数 |
nacos_monitor{name='httpHealthCheck'} | Nacos naming http健康检查次数 |
nacos_monitor{name='tcpHealthCheck'} | Nacos naming tcp健康检查次数 |
nacos 异常指标
指标 | 含义 |
---|---|
nacos_exception_total{name='db'} | 数据库异常 |
nacos_exception_total{name='configNotify'} | Nacos config水平通知失败 |
nacos_exception_total{name='unhealth'} | Nacos config server之间健康检查异常 |
nacos_exception_total{name='disk'} | Nacos naming写磁盘异常 |
nacos_exception_total{name='leaderSendBeatFailed'} | Nacos naming leader发送心跳异常 |
nacos_exception_total{name='illegalArgument'} | 请求参数不合法 |
nacos_exception_total{name='nacos'} | Nacos请求响应内部错误异常(读写失败,没权限,参数错误) |
client metrics
指标 | 含义 |
---|---|
nacos_monitor{name='subServiceCount'} | 订阅的服务数 |
nacos_monitor{name='pubServiceCount'} | 发布的服务数 |
nacos_monitor{name='configListenSize'} | 监听的配置数 |
nacos_client_request_seconds_count | 请求的次数,包括多种(url,方法,code) |
nacos_client_request_seconds_sum | 请求的总耗时,包括多种(url,方法,code) |
Nacos-Sync监控
随着Nacos 0.9版本发布,Nacos-Sync 0.3版本支持了metrics监控,能通过metrics数据观察Nacos-Sync服务的运行状态,提升了Nacos-Sync的在生产环境的监控能力。 整体的监控体系的搭建参考Nacos监控手册
grafana监控Nacos-Sync
和Nacos监控一样,Nacos-Sync也提供了监控模版,导入监控模版
Nacos-Sync监控同样也分为三个模块:
-
nacos-sync monitor展示核心监控项
-
nacos-sync detail和alert展示监控曲线和告警
Nacos-Sync metrics含义
Nacos-Sync的metrics分为jvm层和应用层
jvm metrics
指标 | 含义 |
---|---|
system_cpu_usage | CPU使用率 |
system_load_average_1m | load |
jvm_memory_used_bytes | 内存使用字节,包含各种内存区 |
jvm_memory_max_bytes | 内存最大字节,包含各种内存区 |
jvm_gc_pause_seconds_count | gc次数,包含各种gc |
jvm_gc_pause_seconds_sum | gc耗时,包含各种gc |
jvm_threads_daemon | 线程数 |
应用层 metrics
指标 | 含义 |
---|---|
nacosSync_task_size | 同步任务数 |
nacosSync_cluster_size | 集群数 |
nacosSync_add_task_rt | 同步任务执行耗时 |
nacosSync_delete_task_rt | 删除任务耗时 |
nacosSync_dispatcher_task | 从数据库中分发任务 |
nacosSync_sync_task_error | 所有同步执行时的异常 |
Nacos服务配置性能测试报告
测试目的
主要让大家了解Nacos的性能负载和容量,协助我们更好的管理Nacos性能质量,帮助用户更快的运用评估Nacos系统负荷。
测试工具
我们使用自研的PAS性能评估服务平台进行压测,其原理是基于利用JMeter引擎,使用PAS自动生成的JMeter脚本,进行智能压测。
测试环境
1.环境
指标 | 参数 |
---|---|
机器 | CPU 8核,内存16G |
集群规模 | 单机,3节点,10节点,100节点 |
Nacos版本 | 0.8.0 |
数据库 | 32C128G |
2.设置启动参数
/opt/taobao/java/bin/java -server -Xms4g -Xmx4g -Xmn2g
-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=320m
-Xdebug
-Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSInitiatingOccupancyFraction=70
-XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0
-XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8
-XX:-UseParNewGC -verbose:gc -Xloggc:/home/admin/nacos/logs/nacos_gc.log
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime
-XX:+PrintAdaptiveSizePolicy -Dnacos.home=/home/admin/nacos -XX:-OmitStackTraceInFastThrow
-XX:-UseLargePages -jar /home/admin/nacos/target/nacos-server.jar
--spring.config.location=classpath:/,classpath:/config/,file:./,file:./config/,file:/home/admin/nacos/conf/
测试场景
以下测试场景都是服务配置重要接口:
-
验证Nacos服务发布配置的能力
-
验证Nacos服务获取配置的能力
-
验证Nacos服务监听配置的能力
-
验证Nacos服务长连接容量能力
测试数据
1. 发布配置
发布配置主要测试Nacos publishConfig接口的性能。 在各规模集群的性能表现:
单机 | 3节点 | 10节点 | 100节点 |
---|---|---|---|
1400 | 4214 | 6863 | 8626 |
具体我们看下3节点服务集群发布配置能力。 以下为各个并发数 (施压机台数*并发数) 时,发布配置的TPS,平均RT。
2. 获取配置
获取配置对Nacos getConfig接口进行测试。 实测在各个规模集群的性能表现:
单机 | 3节点 | 10节点 | 100节点 |
---|---|---|---|
15000 | 23013 | 45000 | 161099 |
具体我们也看下3节点服务集群获取配置能力,以下为各个并发数 (施压机台数*并发数) 时,获取配置的TPS,平均RT。
3. 监听配置
执行Nacos addListeners的接口的性能, 监听配置主要采用增加多个配置监听,并多次发布配置的方法,统计发布时间与监听接收到配置时间间隔。 我们选取了几个点,列举了发布与监听时间差,在100ms内基本都能监听到配置的更改。
次数 | 发布与监听时间差(ms) |
---|---|
1 | 63 |
2 | 53 |
3 | 84 |
4 | 73 |
5 | 46 |
6 | 35 |
7 | 73 |
8 | 183 |
9 | 104 |
4. 长连接容量测试
Nacos监听配置与客户端建立长连接,长连接会消耗服务内存,从而集群load增高。建立长连接容量的能力,主要考查配置监听的瓶颈。 测试方法逐渐增加集群的连接,单机连接达到9000时,CPU: 13.9% 内存:18.8%,load:4.7,都处于正常状态,连接数量增加后,load会成倍数级增加。 在各规模集群测试基本上符合验证。
单机 | 3节点 | 10节点 | 100节点 |
---|---|---|---|
9000 | 27000 | 90000 | 910000 |
测试结论
Nacos性能测试都是针对重点功能,通过对各规模集群进行压测,可以看到各个集群的接口容量。 本测试供给大家作为参考,如有不足或偏差,请指正! 如果对性能有其他需求,可以给我们提issue。
Nacos 2.0.0-ALPHA2 配置性能测试报告
测试目的
-
长链接各项业务指标的最高值
-
长链接相比短链接的差异数据对比
测试工具
我们使用自研的PAS性能评估服务平台进行压测,其原理是基于利用JMeter引擎,使用PAS自动生成的JMeter脚本,进行智能压测。
测试环境
1.环境
指标 | 参数 |
---|---|
机器 | CPU 8核,内存16G |
集群规模 | 单机 |
Nacos版本 | Nacos 2.0.0-ALPHA2, Nacos 1.4.0 |
数据库 | 32C128G |
2.设置启动参数
因为grpc使用的直接内存,堆内存相对使用较少,所以jvm参数有所调整
Nacos2.0 gRPC
JAVA_OPT="${JAVA_OPT} -server -Xms9216m -Xmx9216m -XX:MaxDirectMemorySize=4096m -XX:NewSize=4096m -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics -DisPushContent=false -XX:MaxNewSize=4096m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/nacos/logs/java_heapdump.hprof -XX:-UseLargePages -Xloggc:/home/admin/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -DQUERYTIMEOUT=90 -XX:SurvivorRatio=10 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/nacos/logs -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:CMSMaxAbortablePrecleanTime=5000 -XX:CMSInitiatingOccupancyFraction=74 -XX:+UseCMSInitiatingOccupancyOnly -XX:ParallelGCThreads=8 -Dnacos.core.auth.enabled=false "
Nacos1.X HTTP
-server -Xms12880m -Xmx12880m -XX:MaxDirectMemorySize=1024m -XX:NewSize=1024m -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics -DisPushContent=false -XX:MaxNewSize=4096m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/nacos/logs/java_heapdump.hprof -XX:-UseLargePages -Xloggc:/home/admin/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -DQUERYTIMEOUT=90 -XX:SurvivorRatio=10 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/nacos/logs -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:CMSMaxAbortablePrecleanTime=5000 -XX:CMSInitiatingOccupancyFraction=74 -XX:+UseCMSInitiatingOccupancyOnly -XX:ParallelGCThreads=8 -Dnacos.core.auth.enabled=false -Dnacos.member.list= -Djava.ext.dirs=/opt/taobao/java/jre/lib/ext:/opt/taobao/java/lib/ext -Xloggc:/home/admin/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
测试场景
以下测试场景都是服务配置重要接口:
-
验证Nacos服务发布配置的能力
-
验证Nacos服务获取配置的能力
-
验证Nacos服务监听配置的能力
-
验证Nacos服务长连接容量能力
测试方式均是在相同的环境下,使用相同的压力进行测试,分别比对Nacos2.X版本和Nacos1.X版本的性能差异。
测试数据
1. 发布配置
Nacos2.0
tps | 500 | 1000 | 1200 | 1500 | 2000 | 2500 | 3000 |
---|---|---|---|---|---|---|---|
avg rt(ms) | 7 | 8 | 12 | 9 | 9 | 10.89 | 1044 |
80% rt(ms) | 7.9 | 8 | 11 | 9 | 9 | 10.69 | 1581 |
95% rt(ms) | 8.7 | 11 | 25 | 15 | 14 | 24.74 | 2966 |
cpu | 12 | 22 | 28 | 36 | 47 | 55 | 62 |
load | 0.5 | 1.5 | 1.5 | 1.5 | 3.5 | 4 | 5 |
Nacos1.X
tps | 500 | 1000 | 1200 | 1400 | 2000 | 2500 | 3000 |
---|---|---|---|---|---|---|---|
avg rt(ms) | 9 | 8.67 | 8 | 9 | 10 | 11.88 | 1038 |
80% rt(ms) | 9 | 9.4 | 10 | 9 | 10 | 12.48 | 1090 |
95% rt(ms) | 11 | 11.4 | 12 | 14 | 18 | 25.7 | 1170 |
cpu | 14 | 25 | 30 | 35 | 50 | 60 | 65 |
load | 0.9 | 1.4 | 2 | 2.5 | 3 | 2.5 | 3.7 |
结果分析
发布配置两者差别不大,TPS 在2500tps左右出现拐点,http和长链接通道的cpu消耗分布类似。长链接对发布配置提升不大。
2. 获取配置
随机获取200个 5K大小配置
Nacos2.0
tps | 2000 | 4000 | 6000 | 8000 | 10000 | 14000 | 18000(实际15000) |
---|---|---|---|---|---|---|---|
avg rt(ms) | 3.3 | 4 | 3.5 | 5 | 7 | 26 | 133 |
80% rt(ms) | 2.2 | 2.2 | 2.5 | 2.5 | 4 | 41 | 174 |
95% rt(ms) | 3.3 | 4.8 | 5.4 | 24 | 38 | 93 | 238 |
cpu | 12 | 25 | 37 | 48 | 65 | 83 | 85 |
load | 1.2 | 2 | 3 | 4 | 5 | 20 | 36 |
Nacos1.X
tps | 2000 | 4000 | 6000 | 8000 | 10000 | 14000(实际11000) |
---|---|---|---|---|---|---|
avg rt(ms) | 3 | 7.4 | 12 | 22 | 46 | 176 |
80% rt(ms) | 1.8 | 2 | 4 | 7 | 35 | 185 |
95% rt(ms) | 4.4 | 6 | 15 | 33 | 118 | 380 |
cpu | 15 | 30 | 40 | 52 | 60 | 70 |
load | 1.1 | 2.2 | 2.5 | 4 | 5.5 | 9 |
结果分析
长链接支撑的读QPS提升50%,CPU消耗降低50%,http的CPU消耗50%在于请求地址解析
3. 监听配置
两者均为单链接监听200配置。
Nacos2.0
tps | 1500 | 3000 | 6000 |
---|---|---|---|
cpu | 30 | 30 | 60 |
ygc | 0 | 3.75s/次,7次 0.5秒 | 3s/次,10次 1.4秒 |
cmsgc | 0 | 0 | 0 |
load | 6 | 14 | 20 |
Nacos1.X
tps | 3000 | 4000 | 6000 |
---|---|---|---|
cpu | 80% | 90% | 80% |
ygc | 3s一次,10次耗时0.5s | 2s一次,15次耗时1.5s | 1.5s一次,20次耗时1.3秒 |
cmsgc | 3s一次,10次耗时18s | 4.5一次,7次耗时10s | 7.5s一次,4次耗时5s |
load | 6 | 8 | 11 |
结果分析
gRPC以1500tps持续变更推送,可以保证系统指标稳定,超过1500tps,系统内存和load持续升高,但完全没有CMS GC,CPU也维持在较低的水准。 Http 则有较高的CMS GC,GC耗时严重,CPU损耗高。
4. 长连接容量测试
两者均为单链接监听200配置。快上为同时进行大量配置发布。
Nacos2.0
count | 6000 | 8000 | 12000 | 15000 | 21000 | 31500 | 42000 |
---|---|---|---|---|---|---|---|
快上时cpu | 40 | 60 | 80 | 77 | 79 | 80 | 74 |
快上时load | 1.5 | 3 | 3.3 | 3.6 | 5.45 | 5.6 | 6.3 |
快上耗时 | 55s | 55s | 76 | 100 | 80 | 140 | 130 |
稳定时cpu | 1 | 1 | 1 | 1.3 | 2.8 | 1.7 | 2.1 |
稳定时load | 0.3 | 0.5 | 0.5 | 0.8 | 0.9 | 0.8 | 0.8 |
gc | 稳定后无GC消耗 | 稳定后无GC消耗 | 稳定后无GC消耗 | 稳定后无GC消耗 | 稳定后无GC消耗 | 稳定后无GC消耗 | 稳定后无GC消耗 |
Nacos1.X
count | 6000 | 8000 | 12000 | 15000 | 21000 | 31500 | 42000 |
---|---|---|---|---|---|---|---|
快上时cpu | 80 | - | - | - | - | - | - |
快上时load | 8 | - | - | - | - | - | - |
快上耗时 | 100s | - | - | - | - | - | - |
稳定时cpu | 60 | - | - | - | - | - | - |
稳定时load | 1 | - | - | - | - | - | - |
gc | cmsgc频繁,4秒一次 | - | - | - | - | - | - |
结果分析
当连接量达到600时,Nacos1.X的CMS GC已经十分严重,4s一次,基本已经达到极限;反观Nacos2.0,可以继续增长,单从支撑长链接数量角度,Nacos2.0比Nacos1.X支撑7倍以上长链接。
测试结论
单项基础接口压测
-
Nacos2.0读QPS 14000QPS,对比Nacos1.X QPS 8000 提升75%。
-
Nacos2.0写TPS 2500TPS,对比Nacos1.X无明显提升。
-
Nacos2.0支撑长链接40000以上,对比Nacos1.X提升7倍以上。
-
Nacos2.0变更推送1500/s, 对比Nacos1.X无明显提升。
注意
-
本测试为对比Nacos1.X版本的测试场景,仅测试单核心接口的能力值,真实模拟场景压测 将在后续版本给出;
-
本测试供给大家作为参考,如有不足或偏差,请指正! 如果对性能有其他需求,可以给我们提issue。
Nacos服务发现性能测试报告
测试目的
主要了解Nacos的服务发现性能负载和容量,协助我们更好的管理Nacos性能质量,帮助用户更快的运用评估Nacos系统负荷。
测试工具
我们使用自研的PAS性能评估服务平台进行压测,其原理是基于利用JMeter引擎,使用PAS自动生成的JMeter脚本,进行智能压测。
测试环境
1.环境
指标 | 参数 |
---|---|
机器 | CPU 16核,内存32G |
集群规模 | 3节点 |
Nacos版本 | 1.0.0 |
2.设置启动参数
/opt/taobao/java/bin/java -server
-Xms20g
-Xmx20g
-Xmn10g -XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=320m
-XX:-OmitStackTraceInFastThrow
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/admin/nacos/logs/java_heapdump.hprof
-XX:-UseLargePages
-Djava.ext.dirs=/opt/taobao/java/jre/lib/ext:/opt/taobao/java/lib/ext:/home/admin/nacos/plugi
ns/cmdb:/home/admin/nacos/plugins/mysql -Xloggc:/home/admin/nacos/logs/nacos_gc.log
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Xdebug
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
-Dnacos.home=/home/admin/nacos -jar /home/admin/nacos/target/nacos-server.jar
--spring.config.location=classpath:/,classpath:/config/,file:./,file:./config/,file:/home/admin/naco
s/conf/ --logging.config=/home/admin/nacos/conf/nacos-logback.xml nacos.nacos
测试场景
以下测试场景都是服务发现重要接口:
-
验证Nacos服务发现注册实例的能力
-
验证Nacos服务发现查询实例的能力
-
验证Nacos服务发现注销实例的能力
测试数据
1. 注册实例
Nacos服务发现注册实例接口的性能,调用HTTP接口测试。 实测3节点集群不同压力下的性能表现:
机器*并发数 | 服务数 | 注册实例数 | TPS | RT(ms) | 最小RT(ms) | 最大RT(ms) |
---|---|---|---|---|---|---|
1*100 | 80301 | 84965 | 1793.41 | 54.63 | 0.8 | 1200.86 |
3*50 | 529321 | 819226 | 12574.8 | 15.8 | 0.45 | 3499.59 |
4*50 | 609726 | 836870 | 13000 | 18.54 | 0.46 | 3038.48 |
4*100 | 777262 | 927169 | 13257 | 35.65 | 0.48 | 3231.2 |
2. 查询实例
Nacos服务发现查询实例接口的性能,调用HTTP接口测试。 实测3节点集群不同压力下的性能表现:
机器*并发数 | 服务数 | 注册实例数 | TPS | RT(ms) | 最小RT(ms) | 最大RT(ms) |
---|---|---|---|---|---|---|
1*100 | 80301 | 84965 | 3092.16 | 30.86 | 0.81 | 509.4 |
3*50 | 529321 | 819226 | 12574.8 | 15.8 | 0.45 | 3499.59 |
4*50 | 609726 | 836870 | 15603 | 16.41 | 0.42 | 3042.17 |
4*100 | 777262 | 927169 | 13604 | 34.19 | 0.43 | 3434.1 |
3. 注销实例
Nacos服务发现注销实例接口的性能,调用HTTP接口测试。 实测3节点集群不同压力下的性能表现:
机器*并发数 | 服务数 | 注册实例数 | TPS | RT(ms) | 最小RT(ms) | 最大RT(ms) |
---|---|---|---|---|---|---|
1*100 | 80301 | 84965 | 1118.95 | 14.08 | 0.7 | 597.43 |
3*50 | 529321 | 819226 | 14508.53 | 11.23 | 0.4 | 3274.49 |
4*50 | 609726 | 836870 | 15476.93 | 16.02 | 0.38 | 3106.23 |
4*100 | 777262 | 927169 | 11940.9 | 40.33 | 0.42 | 51052.46 |
测试结论
Nacos服务发现性能测试都是针对重点功能,通过对3节点规模集群进行压测,可以看到接口性能负载和容量。
-
压测容量服务数可达60W,实例注册数达110W,集群运行持续稳定,达到预期;(注: 由于本次注册实例使用的是HTTP接口, 并没有将心跳上报的TPS包括在内, 如果要支持百万实例的心跳上报, 需要集群水平扩容, 并调优tomcat和内核参数)
-
注册/查询实例TPS达到 13000 以上,接口达到预期;
本次只测试临时实例注册/查询/注销,未涉及持久实例(后续输出);
本测试供给大家作为参考,如有不足或偏差,请指正! 如果对性能有其他需求,可以给我们提issue。
Nacos2.0.0-ALPHA2 服务发现性能测试报告
测试目的
Nacos2.0对连接模型,服务发现的数据模型也运作模式进行了大范围的重构,因此需要在相同或类似的场景下,了解Nacos2的服务发现性能负载和容量与Nacos1的区别,帮助用户更快的运用评估Nacos系统负荷。
Nacos1.0性能测试参考 服务发现性能测试报告
测试工具
我们使用自研的PAS性能评估服务平台进行压测,其原理是基于利用JMeter引擎,使用PAS自动生成的JMeter脚本,进行智能压测。
测试环境
1. 环境
指标 | 参数 |
---|---|
机器 | CPU 8核,内存16G |
集群规模 | 3节点 |
Nacos版本 | 服务端:Nacos2.0.0-ALPHA2, 客户端:Nacos2.0.0-ALPHA2 |
2.设置启动参数
${JAVA_HOME}/bin/java -DembeddedStorage=true -server -Xms10g -Xmx10g -Xmn4g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/nacos/logs/java_heapdump.hprof -XX:-UseLargePages -Dnacos.member.list= -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext -Xloggc:/home/admin/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dloader.path=/home/admin/nacos/plugins/health,/home/admin/nacos/plugins/cmdb -Dnacos.home=/home/admin/nacos -jar /home/admin/nacos/target/nacos-server.jar --spring.config.additional-location=file:/home/admin/nacos/conf/ --logging.config=/home/admin/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288 nacos.nacos
测试场景
以下测试场景都是服务发现重要接口:
-
验证Nacos服务发现注册实例的能力
-
验证Nacos服务发现查询实例的能力
-
验证Nacos服务发现注销实例的能力
测试数据
1. 注册实例
施压机模拟100个客户端同时发起注册服务,每个客户端一条长连接,每个客户端注册1W个服务。总数100W个服务及实例。
注册完成之后每个客户端继续不停进行注册请求,模拟重复注册请求(会进行更新替换),同时记录下整个过程中的相关数据。
相关API
NamingService.registerInstance(String serviceName, Instance instance)
结果数据如下
施压机数量 | 每台线程数 | 平均TPS | 平均RT | 最小RT | 最大RT | 80%RT(ms) | 95%RT(ms) | 99%RT(ms) | CPU使用率 |
---|---|---|---|---|---|---|---|---|---|
1 | 100 | 7256.32 | 13.14 | 0.39 | 2522.25 | 6.72 | 12.86 | 126.33 | 80% |
2 | 50 | 16418.04 | 5.8 | 0.41 | 3906.77 | 4.0 | 8.88 | 48.84 | 90% |
5 | 20 | 26784.84 | 3.6 | 0.38 | 1606.41 | 3.82 | 8.91 | 30.62 | 90% |
结果分析
相较Nacos1.X版本,注册性能总体提升至少2倍,在服务端机能减半的情况下,服务实例数基本一致的情况下,TPS仍能做到2倍左右的提高。
2. 查询实例
施压机先模拟发起注册服务,总数10W个服务,每个服务10个实例,总数100W实例。
注册完成后,模拟100个客户端同时不停进行随机服务查询请求,并且有实例长度校验。同时记录下整个过程中的相关数据。
相关API
NacosNamingService.getAllInstances(String serviceName, boolean subscribe)
注意 subscribe 为 false 进行测试,否则将会优先查询客户端缓存。
结果数据如下
施压机数量 | 每台线程数 | 平均TPS | 平均RT | 最小RT | 最大RT | 80%RT(ms) | 95%RT(ms) | 99%RT(ms) | CPU使用率 |
---|---|---|---|---|---|---|---|---|---|
1 | 100 | 12998.46 | 7.54 | 0.55 | 213.86 | 9.68 | 10.69 | 27.92 | 40% |
2 | 50 | 12785.01 | 7.93 | 0.38 | 900.48 | 8.34 | 14.18 | 33.04 | 40% |
2 | 100 | 18451.78 | 10.63 | 0.6 | 829.42 | 11.95 | 23.79 | 44.19 | 45% |
5 | 20 | 30680.48 | 3.12 | 0.46 | 1138.38 | 4.33 | 5.9 | 9.57 | 50% |
结果分析
相较Nacos1.X版本,查询性能总体提升至少3倍,在服务端机能减半的情况下,服务实例数基本一致的情况下,TPS仍能做到3倍左右的提高,单机多线程场景甚至有10倍的提升。
3. 注销实例
施压机先模拟100个客户端同时发起注册服务,每个客户端一条长连接,每个客户端注册1W个服务。总数100W个服务及实例。
注册完成后,模拟使用相同100个客户端同时不停进行随机服务注销请求,同时记录下整个过程中的相关数据。
相关API
NacosNamingService.deregisterInstance(String serviceName, String ip, int port)
结果数据如下
施压机数量 | 每台线程数 | 平均TPS | 平均RT | 最小RT | 最大RT | 80%RT(ms) | 95%RT(ms) | 99%RT(ms) | CPU使用率 |
---|---|---|---|---|---|---|---|---|---|
1 | 100 | 9614.96 | 9.88 | 0.41 | 1115.27 | 8.85 | 15.32 | 104.76 | 70% |
2 | 50 | 22252.07 | 4.28 | 0.39 | 856.1 | 4.03 | 5.65 | 31.02 | 90% -> 60% |
5 | 20 | 29393.8 | 2.55 | 0.42 | 741.09 | 2.67 | 8.91 | 15.85 | 90% -> 60% |
结果分析
相较Nacos1.X版本,注销性能总体提升至少2倍,在服务端机能减半的情况下,服务实例数基本一致的情况下,TPS仍能做到2倍左右的提高。 关于CPU由90% 降低为 60%的场景, 是由于随着注销的的服务和实例增多,重复注销的操作变得频繁,未命中服务和实例的操作会被快速返回且操作量小,因此CPU下降、TPS相对注册略高。
测试结论
Nacos2服务发现性能测试都是针对重点功能,通过对3节点规模集群进行压测,可以看到接口性能负载和容量,以及对比相同/类似场景下Nacos1.X版本的提升。
-
压测时服务及实例容量达到百万级,集群运行持续稳定,达到预期;(该场景没有计算频繁变更导致的频繁推送内容,仅单纯计算容量上线,附带推送的真实场景将在下轮压测报告中给出)
-
注册/注销实例TPS达到 26000 以上,总体较Nacos1.X提升至少2倍,接口达到预期;
-
查询实例TPS能够达到 30000 以上,总体较Nacos1.X提升3倍左右,接口达到预期;
注意
-
本次只测试临时实例注册/查询/注销,未涉及持久实例;
-
本测试为对比Nacos1.X版本的测试场景,仅测试单核心接口的能力值,真实模拟场景压测 将在后续版本给出;
-
本测试供给大家作为参考,如有不足或偏差,请指正! 如果对性能有其他需求,可以给我们提issue。
NacosSync 迁移用户手册
手册目标
-
启动 NacosSync 服务
-
通过一个简单的例子,演示如何将注册到 Zookeeper 的 Dubbo 客户端迁移到 Nacos。
准备工作
启动服务之前,你需要安装下面的服务:
-
64bit OS: Linux/Unix/Mac/Windows supported, Linux/Unix/Mac recommended.
-
64bit JDK 1.8+: downloads, JAVA_HOME settings.
-
MySql 5.6.+
获取安装包
有两种方式可以获得 NacosSync 的安装包:
-
直接下载 NacosSync 的二进制安装包:nacosSync.${version}.zip
-
从 GitHub 上下载 NacosSync 的源码进行构建
Package:
cd nacosSync/
mvn clean package -U
目标文件的路径:
nacos-sync/nacossync-distribution/target/nacosSync.${version}.zip
解压安装包之后,工程的文件目录结构:
nacosSync
├── LICENSE
├── NOTICE
├── bin
│ ├── nacosSync.sql
│ ├── shutdown.sh
│ └── startup.sh
├── conf
│ ├── application.properties
│ └── logback-spring.xml
├── logs
└── nacosSync-server.${version}.jar
初始化数据库
系统默认配置的数据库是Mysql,也能支持其他的关系型数据库。 1.建库,缺省的数据库名字为“nacos_Sync”。 2.数据库表不需要单独创建,默认使用了hibernate的自动建表功能。 3.如果你的环境不支持自动建表,可以使用系统自带的sql脚本建表,脚本放在bin目录下。
数据库配置
数据库的配置文件放在conf/application.properties
中:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/nacos_sync?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
启动服务器
$ nacosSync/bin:
sh startup.sh restart
检查系统状态
1.检查系统日志
日志的路径在nacosSync/logs/nacosSync.log
,检查是否有异常信息。
2.检查系统端口
缺省的系统端口是8081
,你可以自己定义在application.properties
中。
$netstat -ano|grep 8081
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN off (0.00/0/0)
控制台
访问路径:
http://127.0.0.1:8081/#/serviceSync
如果检查没有问题,NacosSync 已经正常启动了,NacosSync 的部署结构:
开始迁移
迁移信息
Dubbo服务的部署信息:
迁移的服务:
Service Name | Version | Group Name |
---|---|---|
com.alibaba.nacos.api.DemoService | 1.0.0 | zk |
添加注册中心集群信息
1.点击左侧导航栏中的“集群配置”按钮,新增加一个集群,先增加一个Zookeeper集群,选择集群类型为ZK。
注意:集群名字可以自定义,但是一旦确认,不能被修改,否则基于此集群增加的任务,在 NacosSync 重启后,将不会恢复成功。
2.同样的步骤,增加NacosSync集群。
3.添加完成后,可以在列表中查询到:
添加同步任务
1.增加一个同步任务,从Zookeeper集群同步到Nacos集群,同步的粒度是服务,Zookeeper集群则称为源集群,Nacos集群称为目标集群。
添加完成之后,可以在服务同步列表中,查看已添加的同步任务:
2.同步完成之后,检查下数据是否同步成功到Nacos集群,可以通过Nacos的控制台进行查询。
3.此刻,数据已经成功从Zookeeper集群同步到了Nacos集群,部署结构如下:
Dubbo 客户端连接到 Nacos 注册中心
Dubbo Consumer客户端迁移
Dubbo 已经支持Nacos注册中心,支持的版本为2.5+,需要增加一个Nacos注册中心的Dubbo扩展插件依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>0.0.2</version>
</dependency>
增加Nacos客户端的依赖:
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>0.6.2</version>
</dependency>
配置Dubbo Consumer的Dubbo配置文件consumer.yaml
,让客户端能够找到Nacos集群。
spring
application
name
demo
service
version
group
dubbo
registry
address
不需要修改代码,配置更新完毕之后,你就可以重启你的应用,使之生效了。
Consumer发布完成之后,目前的部署结构如下:
Dubbo Provider迁移
在升级Provider之前,你需要确保该Provider发布的服务,都已经配置在 NacosSync 中,同步的方式为从Nacos同步到Zookeeper,因为Provider升级连接到Nacos之后,需要确保老的Dubbo Consumer客户端能够在Zookeeper上订阅到该Provider的地址,现在,我们增加一个同步任务:
注意:Nacos服务同步到Zookeeper,不需要填写版本号,你在选择源集群的时候,版本号的输入框会自动隐藏掉。
同步任务完成后,你就可以升级Provider了,升级Provider的方法,参考升级Consumer的步骤。
新的部署结构
-
在升级的过程中,会有新老版本的客户端同时存在,部署结构如下:
-
所有的客户端迁移完成之后,部署结构如下:
现在,Zookeeper集群,NacosSync集群就可以下线了。
注意事项
-
同步任务添加之后,需要确保下服务是否成功同步到目标集群,可以通过目标集群的控制台进行查询。
-
NacosSync 支持高可用集群模式部署,你只需要把数据库配置成同一个即可。
-
如果梳理不清楚订阅和发布的服务,建议可以把服务都做双向同步。
-
Dubbo 客户端目前不支持 Nacos 的权重功能,如果你用到了权重功能,需要重新考虑一下方案是否合适。
Nacos2.0代码存放位置
Nacos代码当前保存在develop分支中,启动方式与Nacos 1.x相同(当前位于v1.x-develop),欢迎贡献。
Nacos 2.0.0 兼容性文档
经过社区的讨论和开发, Nacos 基于长连接的2.0.0版本的核心功能已开发完成,目前2.0.0正式版本已发布,欢迎大家使用。
2.0.0支持Nacos1.X服务端的平滑升降级的能力,详情请查看Nacos2.0升级文档 。
Nacos 2.0.0版本压测
详情见:Nacos2.0服务发现模块压测报告 以及 Nacos2.0配置模块压测报告 。
大规模压测报告将在近期放出。
新版本部署
Nacos2.0版本相比1.X新增了gRPC的通信方式,因此需要增加2个端口。新增端口是在配置的主端口(server.port)基础上,进行一定偏移量自动生成。
端口 | 与主端口的偏移量 | 描述 |
---|---|---|
9848 | 1000 | 客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求 |
9849 | 1001 | 服务端gRPC请求服务端端口,用于服务间同步等 |
使用VIP/nginx请求时,需要配置成TCP转发,不能配置http2转发,否则连接会被nginx断开。
客户端拥有相同的计算逻辑,用户如同1.X的使用方式,配置主端口(默认8848),通过相同的偏移量,计算对应gRPC端口(默认9848)。
因此如果客户端和服务端之前存在端口转发,或防火墙时,需要对端口转发配置和防火墙配置做相应的调整。
其余部署参考Nacos部署手册 ,将版本相关替换成2.0.0。
兼容性
Nacos2.0的服务端完全兼容1.X客户端。Nacos2.0客户端由于使用了gRPC,无法兼容Nacos1.X服务端,请勿使用2.0以上版本客户端连接Nacos1.X服务端。
功能完成度及旧版本客户端适配情况:
配置中心
JAVA SDK
-
完全兼容1.X客户端所有API接口方法;
-
完全实现2.0客户端所有API接口方法。
其他语言 SDK
-
完全兼容
openAPI
-
完全兼容所有配置中心相关openAPI。
服务发现
JAVA SDK
-
完全兼容1.X客户端所有API接口方法;
-
完全兼容2.0客户端所有API接口方法;
其他语言 SDK
-
完全兼容所有服务发现相关openAPI。
openAPI
-
注册实例(支持)
-
注销实例(支持)
-
修改实例(支持)
-
查询实例列表(支持)
-
查询实例详情(支持)
-
发送实例心跳(支持)
-
创建服务(支持)
-
删除服务(支持)
-
修改服务(支持)
-
查询服务(支持)
-
查询服务列表(支持)
-
查询系统开关(支持)
-
修改系统开关(支持)
-
查看系统当前数据指标(支持)
-
查看当前集群Server列表(支持)
-
查看当前集群leader(将废弃)
-
更新实例的健康状态(支持)
-
批量更新实例元数据(支持)
-
批量删除实例元数据(支持)
控制台
-
完全兼容配置中心相关页面及功能
-
完全兼容权限控制相关页面及功能
-
完全兼容命名空间相关页面及功能
-
完全兼容集群管理相关页面及功能
-
完全兼容服务发现相关页面及功能
生态兼容情况
Spring Cloud Alibaba
可通过指定nacos-client方式,提前使用Nacos2.0长连接功能
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.5.RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.1.5.RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.0.0-BETA</version>
</dependency>
Dubbo
Nacos2.0版本客户端重新适配了Dubbo2.7.X。并且Dubbo社区正在对新版本进行修改,不再强依赖反射,详情请看 Dubbo#7291
Nacos Spring Boot
Nacos spring boot 将会发布新版本适配2.0.0客户端。
使用方式
SDK客户端、控制台
Nacos 2.0.0版本使用方式和Nacos1.X版本使用完全一致。客户端接口请参考Nacos1.X的SDK文档。
服务端
Nacos 2.0.0服务端的使用也和旧版本没有太大区别,这里对新版本中新增的数个配置参数进行说明
参数 | 默认值 | 描述 |
---|---|---|
nacos.naming.clean.empty-service.interval | 60000(单位毫秒) | Nacos自动清理空服务的工作间隔,将替代旧版本中的nacos.naming.empty-service.clean.period-time-ms 参数 |
nacos.naming.clean.empty-service.expired-time | 60000(单位毫秒) | Nacos判断可清理的空服务的过期时间,当服务没有发布的实例,且超过该过期时间未发生更新后,将被判定为过期空服务而移除 |
nacos.naming.clean.expired-metadata.interval | 5000(单位毫秒) | Nacos自动清理过期元数据的工作间隔 |
nacos.naming.clean.expired-metadata.expired-time | 60000(单位毫秒) | Nacos自动清理过期服务的过期时间,当服务或实例本身被移除超过该设定时间后,元数据信息将会被移除 |
FAQ
能否支持Nacos旧版本客户端?
配置中心兼容支持Nacos1.0起的所有版本客户端,服务发现兼容Nacos1.2起所有版本客户端。 因此建议使用Nacos1.2.0之后版本客户端。 但nacos1.X的客户端不具有长连接能力,因此仍然建议使用Nacos2.0.0客户端。
启动后,调用openAPI 报错 code:503,msg:server is DOWN now, please try again later!
Nacos在1.4版本后使用Jraft替换了自研的Raft实现,Jraft的选主比原先自研的Raft更加严格,会记录之前启动时的ip或host。因此重启时如果ip变动了,有可能造成选主失败,从而导致nacos无法正确提供服务。 解决方式为删除nacos目录下的data,再启动。
或者使用-Dnacos.server.ip=${domain}
,然后将nacos/conf的cluster.conf配置domain列表,避免重启时ip变动导致的raft选主问题。
找不到符号com.alibaba.nacos.consistency.entity
这个包目录是由protobuf
在编译时自动生成,您可以通过mvn compile
来自动生成他们。如果您使用的是IDEA,也可以使用IDEA的protobuf插件。
启动时报错Connection is unregistered.
或Client not connected,current status:STARTING
.
原因是客户端gRPC无法和服务端创建连接,请先使用telnet ${nacos.server.address}:${nacos.server.grpc.port}
进行测试,查看网络是否畅通,服务端端口是否已经正确监听。
若服务端没有问题,查看配置是否有误,服务端和客户端的所配置的端口应一致。
若配置也没有问题,查看是否有防火墙或VIP端口转发问题,Nacos2.0的gRPC端口均通过主端口的偏移量计算产生,因此端口转发也需要满足该偏移量。
Nacos2.0增加了9848,9849端口来进行GRPC通信,我需要在application.properties中额外配置吗?
不需要,这两个端口在Nacos2.0内部是通过8848+1000以及8848+1001这种偏移量方式计算出来的,不需要用户额外在配置文件中配置。但如果使用的是docker或存在端口转发方式启动,需要把这两个端口进行配置。
启动nacos2.0时希望用nginx 代理,9848这个端口怎样处理,要通过nginx暴露出来么?以及docker是否需要映射?
如果存在防火墙或者nginx端口转发问题,需要进行相应的端口暴露配置。如在nginx中,在已经暴露8848(x)的基础上,需要额外暴露9848(x+1000)。
待补充...
Nacos 2.0.0 部署及升级文档
本文档包含两个部分:Nacos2.0.0的部署,以及如何从Nacos1.x平滑升级至Nacos2.0.0。
部署部分,适用于直接部署Nacos2.0.0以上版本的用户。
升级部分,适用于从Nacos1.X版本平滑升级到Nacos2.0.0版本(以及2.0.0-BETA版本)的用户。Nacos2.0.0-ALPHA版本无法进行平滑升级,请勿参照本文档进行升级。
由于Nacos1.X和Nacos2.0的数据结构发生了变化,为了能够完成平滑升降级,需要将数据进行双写,分别生成Nacos1和Nacos2的数据结构进行存储。因此会对性能有一定影响。当集群升级并稳定运行后,可以关闭双写,关闭双写后将会失去平滑降级的功能。
部署步骤
本部分,适用于直接部署Nacos2.0.0以上版本的用户。
1.预备环境准备
Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用:
-
64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
2.下载源码或者安装包
你可以通过源码和发行包两种方式来获取 Nacos。
从 Github 上下载源码方式
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
ls -al distribution/target/
// change the $version to your actual path
cd distribution/target/nacos-server-$version/nacos/bin
下载编译后压缩包方式
您可以从 最新稳定版本 下载 nacos-server-$version.zip
包。
unzip nacos-server-$version.zip 或者 tar -xvf nacos-server-$version.tar.gz
cd nacos/bin
3.启动服务器
Linux/Unix/Mac
单机启动命令(standalone代表着单机模式运行):
sh startup.sh -m standalone
如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:
bash startup.sh -m standalone
单机启动,使用内置数据库(注:使用内置Derby数据库需要保证~/nacos/data/derby-data文件夹下无残留数据):
bash startup.sh -p embedded
集群启动(使用内嵌数据库):
bash startup.sh -p embedded
集群启动(使用外置数据库):
bash startup.sh
4.启动后自检
集群中所有机器部署为2.0.X版本并启动时,应当进行启动之后的检查。
当集群中所有节点logs/naming-server.log日志中观察到upgrade check result true及Upgrade to 2.0.X,便判定为集群准备完毕时,此时才可以使用Nacos2.0。
5.关闭双写
为了节省性能开销,当集群部署完成后,可以先观察一段时间运行情况,当确认无误后,可以关闭双写,从而释放性能,具体的关闭方式是通过API进行:
curl -X PUT 'localhost:8848/nacos/v1/ns/operator/switches?entry=doubleWriteEnabled&value=false'
关闭后可以从logs/naming-server.log
日志中观察到Disable Double write, stop and clean v1.x cache and features
字样。说明关闭双写。
注意,关闭双写后无法在进行平滑降级,请先确认关闭前集群正确运行。
6.关闭服务器
Linux/Unix/Mac
sh shutdown.sh
Windows
cmd shutdown.cmd
或者双击shutdown.cmd运行文件。
升级步骤
以linux系统为例。window系统请自行替换sh
脚本为cmd
脚本。
1. 停止旧节点
选择集群中一台Nacos1.X节点,使用Nacos目录下nacos/bin/shutdown.sh
进行停止。
2. 替换文件
下载并解压缩nacos-server-2.0.2.tar.gz
,将其下的bin
,conf
,target
目录覆盖原Nacos1.X的安装目录下。
3. 修改配置
自行修改nacos/bin/startup.sh
中的JVM参数,conf/cluster.conf
中的集群列表以及conf/application.prpperties
中数据库或其他相关参数。
4. 启动Nacos2.0
使用nacos目录下nacos/bin/startup.sh
启动nacos2.0,其他更多启动指令请查看Nacos部署环境 。
5. 观察是否启动成功
首先查看nacos目录下 logs/start.out
或logs/nacos.log
观察到nacos启动成功的日志,如 Nacos started successfully in cluster mode. use xxx storage
说明程序已启动成功。
之后在观察 logs/naming-server.log
中,可以看到有upgrade check result false
以及 Check whether close double write
等日志信息。
属于正常现象。
6. 升级其他节点
待该节点的服务及实例信息已经同步完毕后(可从控制台进行确认)。重复1~5步骤,将其他的nacos节点也进行升级。
7. 确认升级完成
当集群中最后一个节点也升级到2.0.X版本时,集群会开始进行升级检测。每个节点会对该节点的服务信息和实例信息进行校验,并检测是否还有未完成的双写任务。
当该节点的服务信息和实例信息已经核对成功,并且没有双写任务存在时,该节点会判定自己已经做好升级准备,并修改自己的状态且通知其他Nacos节点。每台节点是否完成升级准备可以从控制台的集群管理中元数据信息中看到"readyToUpgrade": false/true
。
当集群中所有节点均判定为准备完毕时。Nacos集群中的节点会进行升级切换,自动升级到Nacos2.0的处理逻辑。
可以从logs/naming-server.log
日志中观察到upgrade check result true
及Upgrade to 2.0.X
。
####
8.1 关闭双写
当集群升级完成后,可以先观察一段时间运行情况,当确认无误后,可以关闭双写,从而释放性能,具体的关闭方式是通过API进行:
curl -X PUT 'localhost:8848/nacos/v1/ns/operator/switches?entry=doubleWriteEnabled&value=false'
关闭后可以从logs/naming-server.log
日志中观察到Disable Double write, stop and clean v1.x cache and features
字样。说明关闭双写。
注意,关闭双写后无法在进行平滑降级,请先确认关闭前集群正确运行。
8.2 降级
集群升级完毕后,依旧会进行双写,当升级后发现Nacos2.0存在问题时,可以快速进行降级,降级流程为重复步骤1~6,只是将版本改为对应的1.X版本。
当第一台降级完成后,集群即可观察到logs/naming-server.log
中的upgrade check result false
,且控制台集群管理中,所有新版本"readyToUpgrade": false
。
升级相关的openAPI
在2.0.2版本中,nacos-server提供了一些方便查看升级状态及不同版本中的数据区别,方便用户排查升级中的问题。
查看统计
描述
查看当前升级状态
请求类型
GET
请求URL
/nacos/v1/ns/upgrade/ops/metrics
请求参数
无
返回参数
参数类型 | 描述 |
---|---|
string | 升级状态 |
示例
upgraded = true
isAll20XVersion = true
isDoubleWriteEnabled = false
doubleWriteDelayTaskCount = 0
serviceCountV1 = 0
instanceCountV1 = 0
serviceCountV2 = 0
instanceCountV2 = 0
subscribeCountV2 = 0
responsibleServiceCountV1 = 0
responsibleInstanceCountV1 = 0
ephemeralServiceCountV2 = 0
persistentServiceCountV2 = 0
ephemeralInstanceCountV2 = 0
persistentInstanceCountV2 = 0
service.V1.not.in.V2 =
service.V2.not.in.V1 =
查询服务
描述
查询对应Nacos版本中一个服务内容
请求类型
GET
请求路径
/nacos/v1/ns/upgrade/ops/service
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
ver | 字符串 | 否 | 版本 v1 或者 v2 , 默认v2 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/upgrade/ops/service?serviceName=nacos.test.2'
示例返回
{
metadata: { },
groupName: "DEFAULT_GROUP",
namespaceId: "public",
name: "nacos.test.2",
selector: {
type: "none"
},
protectThreshold: 0,
clusters: [
{
healthChecker: {
type: "TCP"
},
metadata: { },
name: "c1"
}
]
}
查询服务列表
描述
查询对应Nacos版本的服务列表
请求类型
GET
请求路径
/nacos/v1/ns/upgrade/ops/service/list
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
pageNo | int | 是 | 当前页码 |
pageSize | int | 是 | 分页大小 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
ver | 字符串 | 否 | 版本 v1 或者 v2 , 默认v2 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/upgrade/ops/service/list?pageNo=1&pageSize=2'
示例返回
{
"count":148,
"doms": [
"nacos.test.1",
"nacos.test.2"
]
}
查询实例列表
描述
查询对应Nacos版本中某个服务下的实例列表
请求类型
GET
请求路径
/nacos/v1/ns/upgrade/ops/instance/list
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
clusters | 字符串,多个集群用逗号分隔 | 否 | 集群名称 |
healthyOnly | boolean | 否,默认为false | 是否只返回健康实例 |
ver | 字符串 | 否 | 版本 v1 或者 v2 , 默认v2 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/upgrade/ops/instance/list?serviceName=nacos.test.1'
示例返回
{
"dom": "nacos.test.1",
"cacheMillis": 1000,
"useSpecifiedURL": false,
"hosts": [{
"valid": true,
"marked": false,
"instanceId": "10.10.10.10-8888-DEFAULT-nacos.test.1",
"port": 8888,
"ip": "10.10.10.10",
"weight": 1.0,
"metadata": {}
}],
"checksum": "3bbcf6dd1175203a8afdade0e77a27cd1528787794594",
"lastRefTime": 1528787794594,
"env": "",
"clusters": ""
}
查询实例详情
描述
查询一个对应Nacos版本中某个服务下个某个实例详情。
请求类型
GET
请求路径
/nacos/v1/ns/upgrade/ops/instance
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
ip | 字符串 | 是 | 实例IP |
port | 字符串 | 是 | 实例端口 |
namespaceId | 字符串 | 否 | 命名空间ID |
cluster | 字符串 | 否 | 集群名称 |
healthyOnly | boolean | 否,默认为false | 是否只返回健康实例 |
ephemeral | boolean | 否 | 是否临时实例 |
ver | 字符串 | 否 | 版本 v1 或者 v2 , 默认v2 |
示例请求
curl -X GET '127.0.0.1:8848/nacos/v1/ns/upgrade/ops/instance?serviceName=nacos.test.2&ip=10.10.10.10&port=8888&cluster=DEFAULT'
示例返回
{
"metadata": {},
"instanceId": "10.10.10.10-8888-DEFAULT-nacos.test.2",
"port": 8888,
"service": "nacos.test.2",
"healthy": false,
"ip": "10.10.10.10",
"clusterName": "DEFAULT",
"weight": 1.0
}
添加服务
描述
补充添加一个服务到对应Nacos版本下
请求类型
POST
请求路径
/nacos/v1/ns/upgrade/ops/service
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
protectThreshold | 浮点数 | 否 | 保护阈值,取值0到1,默认0 |
metadata | 字符串 | 否 | 元数据 |
selector | JSON格式字符串 | 否 | 访问策略 |
ver | 字符串 | 否 | 版本 v1 或者 v2 , 默认v2 |
示例请求
curl -X POST '127.0.0.1:8848/nacos/v1/ns/service?serviceName=nacos.test.2&metadata=k1%3dv1'
示例返回
ok
删除服务
描述
从对应Nacos版本中删除一个服务,如果删除v2服务,只有当服务下实例数为0时允许删除。
请求类型
DELETE
请求路径
/nacos/v1/ns/upgrade/ops/service
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
namespaceId | 字符串 | 否 | 命名空间ID |
ver | 字符串 | 否 | 版本 v1 或者 v2 , 默认v2 |
示例请求
curl -X DELETE '127.0.0.1:8848/nacos/v1/ns/service?serviceName=nacos.test.2'
示例返回
ok
注册实例
描述
注册一个实例到对应Nacos版本的服务下。
请求类型
POST
请求路径
/nacos/v1/ns/upgrade/ops/instance
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
ip | 字符串 | 是 | 服务实例IP |
port | int | 是 | 服务实例port |
namespaceId | 字符串 | 否 | 命名空间ID |
weight | double | 否 | 权重 |
enabled | boolean | 否 | 是否上线 |
healthy | boolean | 否 | 是否健康 |
metadata | 字符串 | 否 | 扩展信息 |
clusterName | 字符串 | 否 | 集群名 |
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
ephemeral | boolean | 否 | 是否临时实例 |
ver | 字符串 | 否 | 版本 v1 或者 v2 , 默认v2 |
示例请求
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?port=8848&healthy=true&ip=11.11.11.11&weight=1.0&serviceName=nacos.test.3&encoding=GBK&namespaceId=n1'
示例返回
ok
注销实例
描述
删除对应Nacos版本服务下的一个实例。
请求类型
DELETE
请求路径
/nacos/v1/ns/upgrade/ops/instance
请求参数
名称 | 类型 | 是否必选 | 描述 |
---|---|---|---|
serviceName | 字符串 | 是 | 服务名 |
groupName | 字符串 | 否 | 分组名 |
ip | 字符串 | 是 | 服务实例IP |
port | int | 是 | 服务实例port |
clusterName | 字符串 | 否 | 集群名称 |
namespaceId | 字符串 | 否 | 命名空间ID |
ephemeral | boolean | 否 | 是否临时实例 |
ver | 字符串 | 否 | 版本 v1 或者 v2 , 默认v2 |
示例请求
curl -X DELETE '127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.test.1&ip=1.1.1.1&port=8888&clusterName=TEST1'
示例返回
ok
升级过程中可能遇到的问题
1. 最后一台节点升级完成时,注册的服务出现波动(变成不健康或暂时被摘除)
升级过程中,为了节约性能,双写的内容仅是内容发生变更时的状态,心跳等内容不会被双写,因此切换版本时,可能有部分实例的心跳过久而健康检查又刚好开始执行,从而被标记非健康或摘除。
后续心跳处理将会把数据补充回来,最终会一致。
2. 升级完成后,升级的最后一台服务端报错Server is DOWN
这可能是因为Raft选主失败导致的,解决方法是重启最后一台升级的服务端。或先将最后一台服务端降级,之后再重新进行一次升级即可。
如何贡献
我们非常欢迎您的贡献和加入,无论是微不足道的清理或大的新功能。我们希望为每个编程语言提供高质量、有良好文档的代码。
这也不是代码是唯一有贡献项目的方式。我们非常重视文档、与其他项目的集成,并欣然接受这些方面的改进。
联系我们
Nacos Gitter-https://gitter.im/alibaba/nacos
Nacos 微博-https://weibo.com/u/6574374908
Nacos segmentfault-https://segmentfault.com/t/nacos
邮件列表
邮件列表建议讨论任何与Nacos有关的事情。具体请看参考手册描述如何订阅我们的邮件列表。
-
dev-nacos@googlegroups.com: 开发邮件列表。如果你在使用或开发Nacos中遇到任何问题,可以在这里提问题。
-
commits-nacos@googlegroups.com: 所有提交将被发送到这个邮件列表。如果你有兴趣Nacos的发展,你可以订阅它。
-
users-nacos@googlegroups.com: 在Github中提问题、更新和提交需求将被发送到这个邮件列表。
贡献代码
贡献代码须知
请贡献代码时候,请先确认和检查以下内容:
阅读Nacos代码规约 ,并根据指引设置IDE的codeStyle及校验插件。
如果变化不大,请编写一些覆盖新功能的单元测试。
如果你正在引入一个全新的特性或API,那么首先启动wiki并在基本设计上达成共识,再开始投入。
贡献流程
这是贡献者的大致工作流程:
-
fork当前存储github库。
-
创建一个分支,作为贡献的基础,这通常是develop分支。
-
做出一些变更提交。
-
确保提交消息的格式正确(见下文)。
-
推送变更到你的fork仓库中。
-
按照拉取请求模板中的清单进行操作。
-
在发送拉取请求之前,请将您的fork仓库与远程存储库同步,这将使您的拉取请求变得简单明了。详情见下面的指南:
git remote add upstream git@github.com:alibaba/nacos.git
git fetch upstream
git rebase upstream/master
git checkout -b your_awesome_patch
... add some work
git push origin your_awesome_patch
-
提交pull request 到 alibaba/nacos,等待回复。如果回复的慢,请无情的催促。
-
详细的贡献流程可参考贡献流程
贡献文档
贡献文档须知
请贡献文档时候,请先确认和检查以下内容:
已确认过文档确实有误或存在缺失。
熟悉Markdown 。
熟悉docsite ,至少能够根据官方文档README.md 的引导完成本地调试
贡献流程
可参考贡献流程
成为提交者
我们会积极纳入新的贡献者。我们更关注的是一系列的持续贡献,良好的品味和对项目维护的持续兴趣。如果你想成为一个提交者(Committer),请让一个现有的提交者(Committer)知道,他们会帮助你通过贡献加入我们。
现在,我们有几个重要的贡献点:
Wiki & JavaDoc
Nacos Console
Nacos SDK(C++.Net\Php\Python\Go\Node.js)
前提
如果你想贡献以上的项,请你必须遵守我们的一些先决条件:
可读性,一个API必须具有JavaDoc,一些非常重要的方法也必须有JavaDoc。
可测性,关于测试过程的单元测试覆盖率(80%)
可维护性,可满足我们的代码规约 ,以及至少3个月的更新频率
可部署性,我们可以鼓励您部署到maven repository
Nacos 贡献流程
此贡献流程适用于所有的Nacos社区内容,包括但不限于Nacos
、Nacos wiki/doc
、Nacos SDK
。
以下以贡献Nacos
为例,详细说明贡献流程。
1. fork Alibaba/Nacos 项目到您的github库
2. 克隆或下载您fork的Nacos代码仓库到您本地
git clone ${your fork nacos repo address}
cd nacos
3. 添加Alibaba/Nacos仓库为upstream仓库
git remote add upstream https://github.com/alibaba/nacos.git
git remote -v
origin ${your fork nacos repo address} (fetch)
origin ${your fork nacos repo address} (push)
upstream https://github.com/alibaba/nacos.git (fetch)
upstream https://github.com/alibaba/nacos.git (push)
git fetch origin
git fetch upstream
4. 选择一个开发的基础分支,通常是upstream/develop,并基于此创建一个新的分支
(从远程仓库拉取分支到本地)
git checkout -b upstream-develop upstream/develop
(从本地分支创建开发分支, 通常以该PR对应的issue号作为开发分支名)
git checkout -b develop-issue#${issue-number}
5. 在本地新建的开发分支上进行各种修改
首先请保证您阅读并正确设置Nacos code style
, 相关内容请阅读Nacos 代码规约 。
修改时请保证该分支上的修改仅和issue相关,并尽量细化,做到一个分支只修改一件事,一个PR只修改一件事。
同时,您的提交记录请尽量使用英文描述,主要以谓 + 宾进行描述,如:Fix xxx problem/bug
。少量简单的提交可以使用For xxx
来描述,如:For codestyle
。 如果该提交和某个ISSUE相关,可以添加ISSUE号作为前缀,如:For #10000, Fix xxx problem/bug
。
6. Rebase 基础分支和开发分支
您修改的时候,可能别人的修改已经提交并被合并,此时可能会有冲突,这里请使用rebase命令进行合并解决,主要有2个好处:
-
您的提交记录将会非常优雅,不会出现
Merge xxxx branch
等字样 -
rebase后您分支的提交日志也是一条单链,基本不会出现各种分支交错的情况,回查时更轻松
git fetch upstream
git rebase -i upstream/develop
OR
git checkout upstream-develop
git pull
git checkout develop-issue#${issue-number}
git rebase -i upstream-develop
如果您使用的是Intellij IDEA,建议使用IDE的版本管理模块,有可视化界面,更方便解决冲突和squash操作
7. 将您开发完成rebase后的分支,上传到您fork的仓库
git push origin develop-issue#${issue-number}
8. 按照拉取请求模板中的清单创建Pull Request
Nacos社区将会Review您的Pull Request,并可能提出修改意见,您可以根据修改意见回到步骤5进行修改,并使用步骤6进行重新提交。
如果您再次提交时提示您存在提交记录冲突,这是因为您修改期间,有其他的修改合并到了基础分支,您rebase后,commit ID发生了变化,此时需要force push 到您的fork分支上即可
9. 如果没有问题,Nacos社区将会把您的修改合并到基础分支中,恭喜您成为Nacos的官方贡献者。
提交需求模板
请不要只提交需求而不创建问题。
What is the purpose of the change
XXXXX
Brief changelog
XX
Verifying this change
XXXX
Follow this checklist to help us incorporate your contribution quickly and easily:
-
Make sure there is a Github issue filed for the change (usually before you start working on it). Trivial changes like typos do not require a Github issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
-
Format the pull request title like
[ISSUE #123] Fix UnknownException when host config not exist
. Each commit in the pull request should have a meaningful subject line and body. -
Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
-
Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add integration-test in test module.
-
Run
mvn -B clean apache-rat:check findbugs:findbugs
to make sure basic checks pass. Runmvn clean install -DskipITs
to make sure unit-test pass. Runmvn clean test-compile failsafe:integration-test
to make sure integration-test pass. -
If this contribution is large, please file an Apache Individual Contributor License Agreement.
如何提交问题报告
如果Nacos项目的任何部分存在问题或文档问题,请通过opening an issue告诉我们。我们非常认真地对待错误和错误,在产品面前没有不重要的问题。不过在创建错误报告之前,请检查是否存在报告相同问题的issues。
为了使错误报告准确且易于理解,请尝试创建以下错误报告:
-
具体到细节。包括尽可能多的细节:哪个版本,什么环境,什么配置等。如果错误与运行Nacos服务器有关,请附加Nacos日志(具有Nacos配置的起始日志尤为重要)。
-
可复现。包括重现问题的步骤。我们理解某些问题可能难以重现,请包括可能导致问题的步骤。如果可能,请将受影响的Nacos数据目录和堆栈strace附加到错误报告中。
-
不重复。不要复制现有的错误报告。
在创建错误报告之前,最好阅读下Elika Etemad关于提交好错误报告的文章,相信 会给你启发。
我们可能会要求您提供更多信息以查找错误。将关闭重复的错误报告。
如何提交安全问题
如果您发现Nacos项目中存在安全问题,请通过ASRC(Alibaba Security Response Center阿里安全响应中心) 告知我们。
社区
联系我们
Nacos Gitter-https://gitter.im/alibaba/nacos
Nacos 微博-https://weibo.com/u/6574374908
Nacos segmentfault-https://segmentfault.com/t/nacos
邮件列表
邮件列表建议讨论任何与Nacos有关的事情。具体请看参考手册描述如何订阅我们的邮件列表。
-
dev-nacos@googlegroups.com: 开发邮件列表。如果你在使用或开发Nacos中遇到任何问题,可以在这里提问题。
-
commits-nacos@googlegroups.com: 所有提交将被发送到这个邮件列表。如果你有兴趣Nacos的发展,你可以订阅它。
-
users-nacos@googlegroups.com: 在Github中提问题、更新和提交需求将被发送到这个邮件列表。
Nacos DingDing group
Welcome to join Nacos community nail group
开发者
Nacos开发者角色
Nacos开发者包含Maintainer、Committer、Contributor三种角色,每种角色的标准定义如下。
Maintainer
Maintainer是对Nacos项目(包括nacos-group下的项目)的演进和发展做出显著贡献的个人。具体包含以下的标准:
-
完成多个关键模块或者工程的设计与开发,是项目的核心开发人员;
-
持续的投入和激情,能够积极参与社区、官网、issue、PR等项目相关事项的维护;
-
在社区中具有有目共睹的影响力,能够代表Nacos参加重要的社区会议和活动;
-
具有培养Committer和Contributor的意识和能力;
Committer
Committer是具有Nacos仓库写权限的个人,包含以下的标准:
-
能够在长时间内做持续贡献issue、PR的个人;
-
参与issue列表的维护及重要feature的讨论;
-
参与code review;
Contributor
Contributor是对Nacos项目有贡献的个人,标准为:
-
提交过PR并被合并;
Nacos开发者权利及义务
开发团队
本页面展示了Nacos的开发团队,并且还在持续扩充中。
###
活跃贡献者
Github 账号 | 名字 | 组织 | 角色 | 邮箱 |
---|---|---|---|---|
wfnuser | 黄清昊 | 阿里巴巴 | Contributor | wfnuser@hotmail.com |