Nacos 是阿里提供的一个“全站式”的,用于发现、配置和管理微服务的解决方案。
目前大有取代 Eureka、Config & Bus 的趋势。
Nacos Config
Nacos Config vs Spring Cloud Config & Bus
在接触 Nacos Config 之前,用得最多的是 Spring Cloud 自带的 Cofing & Bus。关于更多 Spring Cloud Config & Bus 内容可以查看:Spring Cloud 核心组件:Config & Bus。
使用 Spring Cloud Cofig & Bus 已经几乎能够满足绝大多数配置相关的需求。为什么还需要使用 Nacos?作为后来者的 Nacos 相比于 Sping Cloud Config & Bus 提供了哪些新功能,或者说解决了哪些痛点?
Spring Cloud Cofig & Bus 支持外部动态配置没错,但不够完美
使用 Spring Cloud Cofig & Bus 实现动态配置,通常还需要搭配 Git 使用。一些比较照顾运维的公司,会将修改 Git 上配置文件的功能做到自己的系统(在运维修改完配置文件后,调用 Git API,同时要将自己运维系统的用户权限和 Git 账号权限挂勾),会增加一定的开发工作量;而一些放在运维系统资源较少的公司,甚至会直接让运维直接在 Git 编辑界面上去修改配置,但这种配置文件的修改提交,通常不会经过校验,没有经过校验的提供可能会引发意外(yaml 的缩进问题,错手删除了不能删除的配置等等),同时由于没有经过运维系统直接使用 Git 账号,会增加恶意覆盖配置的风险。至于想针对不同运维人员修改不同环境的配置文件,只能通过使用不同的 Git Respository 来隔离,微服务本身就多,加上不同的环境有不同的 Respository ,会导致 Respository 数量爆炸,各种配置文件分散各地。
正是因为 Spring Cloud Cofig & Bus 本身不存储管理配置文件,要求 Spring Cloud Cofig & Bus 时刻监听 Git 上配置文件变化与否也不现实。所以导致使用 Spring Cloud Cofig & Bus 的话, 需要在每次修改完 Git 配置文件后,执行生效请求来通知 Spring Cloud Cofig & Bus 配置更新。
Nacos Config 本身就提供配置文件的存储和更新服务,同时还有完整的权限管理功能。可谓是一站式解决方案。运维可以通过不同的账号登录 Nacos 自带的管理系统,修改自身账号权限下的配置文件,一旦保存立即生效,无须额外发送生效请求。
Sping Cloud Config & Bus 的隔离颗粒度不尽合理
Sping Cloud Config & Bus 能通过
spring.cloud.config.label
(配置文件所在的 Git 分支)、spring.cloud.config.name
(配置文件名的主要部分) 和spring.cloud.config.profile
(配置文件名的环境描述部分)来区分不同配置。而据我所知,日常使用都是一个微服务的配置文件放在一个 Git Respository,也就是spring.cloud.config.label
固定是 master,而spring.cloud.config.name
也固定与spring.application.name
相同,仅通过spring.cloud.config.profile
来区分不同环境的不同配置。Nacos Config 除了能使用原生的
spring.profiles.active
进行隔离以外,还提供了 Namespace、Group、DataId 三层隔离配置方式。其实 Sping Cloud Config & Bus 也能按照 Nacos Config 进行那样的划分:使用不同的
spring.cloud.config.label
代表不同的环境,再通过不同的spring.cloud.config.name
代表该微服务属于那个组,最后使用spring.cloud.config.profile
代表该微服务的具体名称。但如果这样划分又会和 Sping Cloud Config & Bus 本身设计这些属性的语义造成冲突。
Sping Cloud Config & Bus 需要自己搭建微服务
使用 Sping Cloud Config & Bus 通常要自己专门搭建一个配置微服务来负责管理配置,其他微服务则接入这个配置微服务来实现动态配置。相当于配置中心的服务端和客户端都是由用户负责。
而 Nacos 则可以直接安装使用,用户只需要专注于那些微服务需要接入到 Nacos ,用户只需要负责客户端。
Nacos 的三层隔离配置
Nacos 中有 Namespace、Group、DataId 三层隔离配置:
Namespace
:命名空间,Nacos 默认提供了 public。通常用作隔离不同的环境,如 dev、prod、test 等Group
:组类别,Nacos 默认提供了 DEFAULT_GROUP。通常用将不同的微服务归类到同一个类别里DataId
:配置文件/配置集的 Id,通常与微服务的 application.name 同名,基本等同于具体的 Service
在不指定 spring.profiles.active
时,三者可以唯一确定一份配置文件,在项目的 bootstrap.yaml 文件中可以指定:
1 | spring: |
这时候拉取的是 public 命名空间下的,DEFAULT_GROUP 组中的 nacos-config.yaml 配置文件。
当指定 spring.profiles.active=dev
时,拉取的是 public 命名空间下的,DEFAULT_GROUP 组中的 nacos-config-dev.yaml 配置文件。
也就是说完整 DataId 格式为:
1 | ${prefix}-${spring.profiles.active}.${file-extension} |
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置。spring.profiles.active
即为当前环境对应的 profile。 注意:当spring.profiles.active
为空时,对应的连接符-
也将不存在,DataId 的拼接格式变成${prefix}.${file-extension}
file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。
Nacos 的三种部署方式
Nacos 支持三种部署模式:单机模式(用于本地测试或者单机使用)、集群模式(一般生产环境使用,确保高可用)和多集群模式(适用于多数据中心场景)
单机部署
直接下载安装 Nacos ,运行 sh nacos/bin/startup.sh -m standalone 即可。
集群部署
集群部署是 Nacos 官网推荐我们应用在生产环境下的部署方式。原因和以前的使用 Sping Cloud Config & Bus 也会部署在多台机器上一样,都是为了防止单点故障。
关于集群部署,在 Nacos 的官方文档中,有这么一张图:
可见,官网推荐我们在使用 Nacos 集群部署的时候,对外(要接入 Nacos 的微服务)提供访问域名,这个域名指向一层 VIP(可以使用 Nginx),再由 VIP 负载均衡到具体的 Nacos 集群。
至于如何将 Nginx 和域名关联,并负载均衡到 ip 列表过于简单,不再叙述。
关键是当我们在多台机器上启动了 Nacos,如何将多台机器上的 Nacos 关联在一起。也十分简单,只需要编辑 nacos/conf/cluster.conf (从 nacos/conf/cluster.conf.example 进行复制并删除 .example 所得),并设置 nacos 的 ip list:
1
2
3
4#it is ip
192.168.16.101:8848
192.168.16.102:8848
192.168.16.103:8848再运行 sh nacos/bin/startup.sh 即可。
多集群模式
Nacos 的多集群模式我没有实践过,但根据官网文档描述可以知道多集群模式有如下特点和参数设置:
Nacos 支持 NameServer 路由请求模式,通过它您可以设计一个有用的映射规则来控制请求转发到相应的集群,在映射规则中您可以按命名空间或租户等分片请求 …
- ip-address 参数可以直接设置 Nacos 的 ip
1
nacos.inetutils.ip-address=10.11.105.155
- use-only-site-local-interfaces 参数可以让 Nacos 使用局域网 ip,这个在 Nacos 部署的机器有多网卡时很有用,可以让 Nacos 选择局域网网卡
1
nacos.inetutils.use-only-site-local-interfaces=true
- ignored-interfaces 支持网卡数组,可以让 Nacos 忽略多个网卡
1
2nacos.inetutils.ignored-interfaces[0]=eth0
nacos.inetutils.ignored-interfaces[1]=eth1- preferred-networks 参数可以让 Nacos 优先选择匹配的 ip,支持正则匹配和前缀匹配
1
2nacos.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 的配置持久化
默认情况下 Nacos 使用嵌入式的数据库(Apache Derby)实现配置存储。但是如果同时启动多个默认配置下的 Nacos 节点,就会导致每个 Nacos 节点都有一份嵌入式数据库来存储自身的配置文件,会对 Nacos 集群的数据一致性产生影响。所以这时候 Nacos 会使用集中式的外部存储方式来支持集群化 Nacos 部署,目前只支持 Mysql 的存储。
在配置使用 Mysql 作为 Nacos 的外部存储之前,我们需要先自己建库建表。先手动创建一个名为 nacos_config 的 Mysql 数据库,再执行 Nacos 目录中的 nacos/conf/nacos-mysql.sql 脚本,常见配置、权限相关的表。
再修改 Nacos 目录下的 conf/application.properties 文件,添加以下配置并重启 Nacos,即可实现将配置文件存储在 Mysql,而不是自身的嵌入式数据库:
1 | ... |
Nacos Discovery
Nacos Discovery vs Eureka
关于 Eureka ,以前也写过相关博客,如果感兴趣可以查看:Spring Cloud 核心组件:Eureka
临时实例 or 持久化实例
临时和持久化的区别主要在健康检查失败的后的表现,持久化实例健康检查失败后会被标记成不健康,而临时实例会直接从列表中被删除。
持久化实例存在意义很明显,方便我们看到实例的健康与否,便于做后续的告警、扩容等处理。
而临时实例的特性比较适合那些需要应对流量突增而弹性扩容的服务,当流量降下来后这些实例自己销毁自己就可以了,不用再去 Nacos 里手动调用注销实例。
CP or AP
Eureka 是 AP 类型的注册中心,表现为当客户端因为网络延时或者确实故障,而没有向 Eureka Server 发送心跳时,Eureka 并不会马上将该节点从服务列表中删除。
那么作为 Eureka 的替代方案的 Nacos Discovery 是属于 CP 类型还是 AP 类型?答案是 Both。
Nacos Discovery 支持 AP 和 CP 的切换。
评论