ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Nacos入门指南:微服务注册中心与配置中心实战

Nacos入门指南:微服务注册中心与配置中心实战

1. Nacos是什么,为什么微服务项目离不开它

很多刚接触微服务的同学,第一次听到Nacos这个名字,往往是从同事嘴里蹦出来的——"服务都给我注册到Nacos上去""配置改完了,往Nacos一丢,刷新一下就生效了"。听上去很神秘,其实拆开来看,Nacos就是Naming and Configuration Service,翻译过来就是服务发现与配置管理平台。它是阿里巴巴开源的项目,可以理解成微服务架构里的"通讯录"和"老管家"两个角色合二为一。

先说通讯录这个角色。微服务架构里,一个项目会被拆成几十个服务,服务A要调用服务B,总不能把B的IP地址和端口写死在配置文件里——B如果扩容、迁移、宕机重启,IP一变,A就找不到它了。这时候Nacos站出来说:所有服务启动后都到我这里报个到,记下你的名字、IP和端口;谁要调用谁,不用背地址,直接来问我"某某服务现在有几个活的实例、分别在哪",这就是服务注册与发现。

再说老管家这个角色。传统项目改一个配置项,比如数据库连接池大小、某个业务开关,代码改完要重新打包、重启服务,在微服务几十个节点都来一遍,极其痛苦。Nacos提供了配置管理能力:把配置集中存放,业务服务启动时从Nacos拉取,Nacos里的配置一旦变更,服务能实时收到通知并自动刷新,这就是配置中心的动态刷新能力。

这篇内容面向的是第一次接触Nacos的新手,我会把Nacos的核心概念、安装启动、注册中心用法、配置中心用法、以及那些容易踩的安全坑,全部捋一遍。你不需要有很深的中间件基础,跟着走一遍,自己就能把Nacos跑起来。

1.1 一个注册中心要解决的最基本问题

我见过不少新手问:服务之间调用,直接写死IP行不行?行,但前提是你的系统永远不会扩容、不会迁移、不会出故障。现实中只要服务实例超过三五个,写死IP就会变成灾难。

举个例子:你有订单服务、用户服务、支付服务三个模块,用户服务部署了两台机器,假设IP分别是192.168.1.10和192.168.1.11。订单服务要调用用户服务,引入一个负载均衡组件Ribbon,把这两个地址配上去,轮询调用。看起来没问题,可一旦用户服务要做发布升级,先摘掉一台机器,或者机器宕机了,订单服务感知不到,还是会往那个IP上发请求,结果就是一堆连接超时和5xx错误。

有了Nacos之后,时机就完全不同了。用户服务的两个实例启动时,自动向Nacos注册自己的地址;订单服务调用用户服务时,先从Nacos拉取当前可用的实例列表,配合Ribbon或Spring Cloud LoadBalancer做负载均衡。实例下线时,Nacos能通过心跳机制感知到,并把不可用的实例从列表里摘除。整个过程不需要人工改任何配置,服务之间的调用始终只认服务名,不认IP。这就是注册中心最核心的价值。

1.2 配置中心的价值:修改配置不用重启服务

注册中心解决的是"服务在哪"的问题,配置中心解决的是"服务怎么跑"的问题。两者在Nacos里是两个独立但又共用一个平台的功能模块。

我最早接触配置中心时,心里有个疑问:数据库连接串、Redis地址这些东西,我放进代码里或者配置文件里,不也能跑吗?为什么要额外引入一个配置中心?答案是:为了不让"改配置"这件事变成一次发布流程。

微服务架构下,一个配置项的修改可能要推送到所有相关联的服务节点。如果没有配置中心,你要改一个限流阈值,得改代码、提交、构建、发布、重启,整个过程需要运维配合,快的十几分钟,慢的半小时以上。而且配置文件分散在各台服务器上,时间久了极易出现"某台机器配置没更新"的情况。Nacos把配置集中管理后,运维或开发在控制台改一下配置,各服务通过长轮询机制秒级感知变更,内部属性自动刷新,服务不用重启。这个体验,用一次就回不去了。

1.3 新手最容易混淆的角色定位

新手最容易混淆的是Nacos和Spring Cloud Config、Eureka、Consul这些组件的关系。简单说几句:

  • Eureka:只做服务注册与发现,而且Spring Cloud官方已经宣布进入维护模式,新项目基本不再推荐。
  • Consul:也能做注册中心和配置管理,功能很全,但在国内团队的使用基数不如Nacos,中文资料也少一些。
  • Spring Cloud Config:只做配置管理,不负责服务发现,通常要搭配Eureka或Consul用。
  • Nacos:注册中心 + 配置中心二合一,还自带控制台,界面操作直观,适合中小团队,也适合从零起步的微服务项目。

所以对新手来说,选Nacos是一个"一份中间件搞定两件事"的高性价比选择。后续你如果接触Dubbo,也可以直接用Nacos作为注册中心,Dubbo对Nacos的支持也很成熟。

2. 核心概念:服务、实例、命名空间与分组的对应关系

Nacos的控制台里有很多名词,刚打开时容易看晕:命名空间、分组、服务名、实例、保护阈值、数据ID、配置格式……我当初也是一路摸过来的。其实这些概念并不复杂,关键是要搞明白它们之间的层级关系:命名空间 > 分组 > 服务/配置。

如果把Nacos比作一栋大楼,命名空间就是楼里的不同楼层,不同楼层之间业务隔离;分组是同一楼层里的不同房间,同一楼层可以根据业务或环境再细分;服务名和配置就是房间里的具体物品。下面拆开讲。

2.1 从一次服务调用看Nacos的数据模型

假设你有一个电商系统,拆分了商品服务(product-service)和订单服务(order-service)。两个服务启动后,都会向Nacos注册。Nacos里会形成这样一条数据链路:

命名空间:public(默认) └── 分组:DEFAULT_GROUP └── 服务名:product-service └── 实例1:192.168.1.10:8080 └── 实例2:192.168.1.11:8080

订单服务要调用商品服务,就去Nacos查询服务名为product-service下的所有实例,拿到两个地址后,用负载均衡策略选一台发起调用。在Nacos控制台的"服务管理 -> 服务列表"里,你能看到product-service、order-service这些服务名,点进去能看到下面挂着的实例IP、端口、健康状态。

这里面有个很容易忽略的点:服务名必须全局唯一。如果你有两个环境(测试、生产)都用同一个服务名,就会互相干扰,所以需要通过命名空间或分组来做环境隔离,这也是下一节要讲的重点。

2.2 命名空间、分组、服务名、实例的区别与联系

命名空间(Namespace):最粗粒度的隔离单位,用于区分环境或租户。常见做法是创建dev、test、prod三个命名空间,每个环境一套独立注册中心和配置中心数据,互不干扰。Nacos默认有一个public命名空间,不指定的话就默认进这里。需要注意,不同命名空间之间的服务和配置默认不可见,这在多环境部署时非常有用。

分组(Group):命名空间之下的隔离维度。默认分组是DEFAULT_GROUP。一般来说,同一个服务可以建立多个分组,比如按机房、按业务线隔离。不过对大多数中小项目来说,命名空间做环境隔离已经够用,分组保持默认即可。

服务名(Service Name):服务的逻辑标识,一般用spring.application.name或Dubbo的service name。服务名对应一组实例。

实例(Instance):一个具体的服务进程,包含IP、端口、权重、元数据等信息。同一个服务名下面可以挂多个实例,Nacos会通过心跳检查实例的存活状态。

从层级上看,命名空间在最上层,分组在中间,服务/配置在最底层。新手最容易犯的错是在测试环境改配置时,发现改了public命名空间里的内容,但服务读的其实是dev命名空间,结果怎么都不生效。后面配置管理部分我还会再提。

2.3 配置中心的数据ID与文件扩展名

配置中心也有类似的分层逻辑。在Nacos中,每条配置都有一个唯一标识,叫Data ID,通常的命名格式是服务名-环境.扩展名,比如order-service-dev.yaml、product-service-prod.properties。

Data ID由三部分组成:前缀、环境标识、扩展名。前缀一般和Spring Boot的spring.application.name保持一致;环境标识对应profile(dev、test、prod);扩展名决定了配置的解析格式,支持properties、yaml、yml、json、xml等。

这里有个新手经常问的问题:Data ID里要不要带扩展名?必须带。Nacos靠扩展名来识别解析方式,如果你用了yaml格式的配置,但Data ID没有.yml后缀,服务端可能无法正确解析。更严谨的做法是,在Spring Boot项目里通过spring.config.import=nacos:order-service-dev.yaml这样的方式指定Data ID,确保读取的是你期望的那条配置。

3. 环境准备与安装启动:Windows本地与版本匹配

我第一次装Nacos是在Windows上,踩了不少版本和环境的坑。现在整理一份从零到能访问控制台的完整流程,顺便把几个高频问题的排查思路一并说清楚。

3.1 环境要求与版本选择(含JDK、MySQL、ARM版)

Nacos是基于Java开发的,所以JDK是必须的。2.x版本要求JDK 8及以上,推荐JDK 8或11;3.x版本官方推荐JDK 17以上。如果你是本地开发,装个JDK 8或者11,跑2.x版本基本没问题。

数据库方面,Nacos 2.x可以支持内置Derby数据库,也可以切换成MySQL。使用内置Derby时,无需额外配置数据库,直接启动即可,非常省事,适合第一次体验。但如果你要部署到测试环境或生产环境,强烈建议换成MySQL,官方也明确建议生产环境使用MySQL,因为Derby在并发和数据可靠性上都不太够用。

关于MySQL版本,这里有个非常典型的坑:有人用MySQL 8.4.11去连Nacos 2.x,结果启动直接报错或者鉴权失败。原因是MySQL 8.4版本起,默认的认证插件变成了caching_sha2_password,而Nacos 2.x内置的MySQL驱动版本较老,对这套认证方式支持不完善。解决办法有两个:一个是创建Nacos专用账号时显式指定IDENTIFIED WITH mysql_native_password BY '密码';另一个是使用Nacos 2.5.x之后的版本,新版驱动对MySQL 8.x的兼容性更好。建议优先升级Nacos版本,而不是去改数据库认证模式,因为改认证模式在一些云数据库实例上操作较麻烦。

ARM架构:如果你用的是ARM芯片的服务器或开发机,比如某些云平台的ARM实例,注意不要下载x86的发行包。Nacos 2.5.0提供了ARM版本,下载的时候认准nacos-server-2.5.0-arm.tar.gz这类带arm标识的包。如果你用Docker部署,也要选对应的ARM镜像,否则会出现"SIGILL"或"无法执行二进制文件"的报错。

3.2 Windows启动方式与验证

Windows下安装Nacos 2.x,流程很简单:

  1. 去Nacos官方GitHub Releases页面下载nacos-server-x.x.x.zip压缩包,比如2.3.2或2.5.0。
  2. 解压到本地目录,比如D:\nacos。
  3. 进入bin目录,双击startup.cmd(默认以集群模式启动可能不行,需要修改脚本)或用命令行执行。

这里有个非常重要的细节:2.x版本的startup.cmd默认启动模式是集群模式,而集群模式依赖数据库和多个节点,单机跑会启动失败。新手第一次使用,需要修改启动命令:

startup.cmd -m standalone

或者直接改bin目录下的startup.cmd文件,把set MODE="cluster"改成set MODE="standalone"。改完之后,双击执行即可。

启动完成后,浏览器访问http://localhost:8848/nacos,默认账号密码都是nacos/nacos,登录后就能看到控制台首页。8848是Nacos默认HTTP端口,9848是2.x版本gRPC端口,这两个端口在防火墙里都要放开,否则可能出现服务注册成功但调用时偶发失败的情况。

验证注册中心是否正常,最简单的方式是看控制台左侧"服务管理 -> 服务列表",如果里面为空但页面正常显示,说明Nacos已经跑起来了。

3.3 Docker Compose部署Nacos 3.x

很多团队现在倾向于用Docker部署中间件,Nacos 3.x发布后,部署方式也有了明显变化。3.x版本不再内置Derby数据库,而是必须依赖外部数据库,所以Docker Compose部署时需要同时启动MySQL和Nacos。

下面是一个可用的docker-compose.yml示例(MySQL 8 + Nacos 3.x):

version: '3' services: mysql: image: mysql:8.0.36 container_name: nacos-mysql environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: nacos_config MYSQL_USER: nacos MYSQL_PASSWORD: nacos123 ports: - "3306:3306" volumes: - mysql-data:/var/lib/mysql command: --default-authentication-plugin=mysql_native_password nacos: image: nacos/nacos-server:v3.0.0 container_name: nacos-server depends_on: - mysql environment: MODE: standalone NACOS_AUTH_ENABLE: "true" NACOS_AUTH_TOKEN: "your-secret-key-here-please-change-it" SPRING_DATASOURCE_PLATFORM: mysql MYSQL_SERVICE_HOST: mysql MYSQL_SERVICE_DB_NAME: nacos_config MYSQL_SERVICE_PORT: 3306 MYSQL_SERVICE_USER: nacos MYSQL_SERVICE_PASSWORD: nacos123 MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true ports: - "8848:8848" - "9848:9848" volumes: - nacos-logs:/home/nacos/logs volumes: mysql-data: nacos-logs:

需要注意,3.x版本启动后,控制台地址和2.x一样,仍是http://localhost:8848/nacos。但3.x对数据库要求更高,初始化时务必使用官方提供的mysql-schema.sql脚本建库,不要拿2.x的脚本去初始化3.x的库,表结构有差异,可能启动报错。

3.4 数据库初始化脚本

如果你选择使用MySQL存储,首次启动前需要初始化数据库。Nacos发行包的conf目录下自带mysql-schema.sql脚本(2.x版本文件名可能叫nacos-mysql.sql)。

操作步骤:

  1. 创建一个专用数据库,例如nacos_config。
  2. 执行脚本:mysql -u root -p nacos_config < mysql-schema.sql。
  3. 修改conf/application.properties,开启MySQL存储:
spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false db.user.0=nacos db.password.0=nacos123

改完再启动,Nacos启动过程中会自动校验表结构。如果你在Windows启动时看到类似"nacos_config.tables不存在"或"表不存在"的错误,多半是脚本没执行成功,重新执行一遍即可。

4. 注册中心实战:Spring Boot服务接入与调用

Nacos跑起来之后,接下来就是让业务服务注册上去。我这里以Spring Boot 2.7.x + Spring Cloud Alibaba 2021.x为例,把完整接入过程过一遍。

4.1 引入依赖与配置

新建一个Spring Boot项目(比如product-service),pom.xml里引入Spring Cloud Alibaba的Nacos Discovery依赖:

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2021.0.5.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>

然后在application.yml里配置:

server: port: 8080 spring: application: name: product-service cloud: nacos: discovery: server-addr: 127.0.0.1:8848 namespace: dev # 可选,不写默认public group: DEFAULT_GROUP

只需要这几行,启动服务后,你到Nacos控制台的"服务列表"里,就能看到product-service已经出现,实例状态为健康。这里要注意的是,spring.application.name必须和你希望注册的服务名一致,如果不设置,默认会用"application"作为服务名,多个服务会互相覆盖,这在微服务架构里属于低级但常见的错误。

4.2 注册与发现验证

注册之后怎么验证服务发现呢?最简单的办法,创建两个服务,让一个服务调用另一个服务的接口。

服务提供方product-service写一个接口:

@RestController @RequestMapping("/product") public class ProductController { @GetMapping("/info") public String info() { return "product-service-8080"; } }

服务消费方order-service里注入DiscoveryClient,查询可用实例:

@RestController @RequestMapping("/order") public class OrderController { @Autowired private DiscoveryClient discoveryClient; @GetMapping("/callProduct") public String callProduct() { List<ServiceInstance> instances = discoveryClient.getInstances("product-service"); for (ServiceInstance instance : instances) { System.out.println("找到实例: " + instance.getHost() + ":" + instance.getPort()); } if (instances.isEmpty()) { return "no instance"; } ServiceInstance target = instances.get(0); String url = "http://" + target.getHost() + ":" + target.getPort() + "/product/info"; return restTemplate.getForObject(url, String.class); } }

启动order-service后,访问http://localhost:8081/order/callProduct,能看到返回"product-service-8080",说明服务发现和调用链路都通了。如果启动多个product-service实例(比如8080和8082),Nacos服务列表里会显示两个健康实例,调用时轮询到不同端口,这就是负载均衡的基础。

4.3 与Ribbon、Dubbo的协同

新手经常会问:Nacos和Ribbon是什么关系?Nacos负责提供服务实例列表,Ribbon或Spring Cloud LoadBalancer负责从这个列表里按策略挑选一个实例。两者分工不同,不冲突。

Spring Cloud 2021版本之后,默认负载均衡器换成了Spring Cloud LoadBalancer,但底层的策略思路和Ribbon类似。如果你想手动控制负载均衡,可以在消费方的配置里指定:

spring: cloud: loadbalancer: nacos: enabled: true

如果用的是Dubbo + Nacos的组合,情况会稍有不同。Dubbo通过Nacos做服务发现时,注册的数据模型和Spring Cloud不一样,但在控制台里看到的依然是服务名和实例列表。你只需要在Dubbo的配置里指定注册中心地址:

<dubbo:registry address="nacos://127.0.0.1:8848" />

或者用Spring Boot方式:

dubbo.registry.address=nacos://127.0.0.1:8848 dubbo.application.name=order-service

Dubbo和Spring Cloud的调用方式不同,但注册中心的接入方式非常类似。新手不要被"两套体系"搞晕,先掌握任意一套的注册流程,另一套只需要注意配置格式的差异。

5. 配置中心实战:动态刷新与热更新

注册中心搞定后,配置中心是Nacos另一个高频使用场景。这一节我重点讲配置管理的操作流程和动态刷新的实现原理。

5.1 配置管理操作流程

在Nacos控制台,进入"配置管理 -> 配置列表",点击右上角"+"号新建配置。以order-service为例,我通常这样填:

  • Data ID:order-service-dev.yaml
  • 配置格式:YAML
  • 配置内容:写入你的业务配置,比如:
custom: order: timeout: 5000 retry-count: 3

保存后,这条配置就存在Nacos里了。接下来在Spring Boot项目里引入配置中心依赖:

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2021.0.5.0</version> </dependency>

然后在bootstrap.yml(Spring Boot 2.4之前的写法)或application.yml(2.4之后的推荐写法)中指定:

spring: application: name: order-service cloud: nacos: config: server-addr: 127.0.0.1:8848 file-extension: yaml namespace: dev group: DEFAULT_GROUP

启动项目时,Spring Cloud会主动到Nacos拉取Data ID为order-service-dev.yaml的配置,并注入到Spring容器中。这个数据ID的拼装规则是:${spring.application.name}-${spring.profiles.active}.${file-extension},如果你的环境标识是dev,文件扩展名是yaml,那Data ID就必须叫order-service-dev.yaml,否则配置不会被加载。

5.2 热更新实现与@RefreshScope

配置能拉取到只是第一步,真正的价值在于变更后自动刷新。Nacos 2.x的配置中心基于gRPC长连接实现实时推送,当你在控制台修改配置并发布后,客户端能在几秒内感知变更。

但这里有个很多人踩过的坑:虽然配置拉新了,但Bean里的属性值没有更新。原因是Spring容器里的对象是在启动时创建的,属性值已经注入到对象里了,仅仅刷新外部配置源不会自动改掉已创建的对象。解决办法是给对应的类加@RefreshScope注解:

@Component @RefreshScope public class OrderProperties { @Value("${custom.order.timeout}") private int timeout; @Value("${custom.order.retry-count}") private int retryCount; }

加了@RefreshScope之后,配置发生变化时,Spring会重新创建这个Bean,重新注入最新的属性值,从而实现热更新。这个注解本质上让Bean的实例变成"可刷新代理",使用起来很轻量,但要注意它不适合作用在无状态工具类上,频繁刷新会产生不必要的对象重建开销。

还有一种方式是用@NacosValue注解(Nacos原生客户端支持),自动刷新不需要额外加@RefreshScope:

@NacosValue(value = "${custom.order.timeout}", autoRefreshed = true) private int timeout;

不过@NacosValue通常搭配Nacos原生API使用,在Spring Cloud Alibaba体系中,我建议优先用@RefreshScope + @Value,兼容性和维护性更好。

5.3 配置中心常见误区

我在实际项目中见过好几个团队在配置中心上栽跟头,典型的有:

  1. 改了Nacos里的配置,服务半天没反应。先检查Data ID是否匹配、命名空间是否对得上,再检查是否加了@RefreshScope或autoRefreshed=true。大多数"不生效"其实是命名空间或Data ID写错了,服务读的根本不是你改的那条配置。

  2. 配置文件里同时存在本地和Nacos两套配置,本地值把Nacos覆盖了。Spring Cloud Nacos配置的优先级默认高于本地配置文件(spring.config.import方式下优先级有讲究),但如果你在本地配置里写了spring.cloud.nacos.config.enabled=false之类,会直接关掉配置中心。用spring.config.import导入Nacos配置时,务必了解本地配置和Nacos配置的覆盖关系,避免出现"改了Nacos却不生效"的错觉。

  3. DataSource连接信息放在Nacos里,但服务启动时数据库还没就绪,导致启动失败。这种情况要合理设置数据库连接池的初始化策略,或者让Nacos配置中心先于数据源初始化,这是Spring Boot自动装配顺序的问题,前置条件是把Nacos配置加载逻辑放在数据源初始化之前,Spring Cloud Alibaba默认已经处理了依赖顺序,但如果你自定义了DataSource,就要注意启动时序。

6. 安全加固:鉴权、Namespace未授权访问与默认JWT修复

Nacos作为微服务的核心基础设施,往往掌握着所有服务的地址和敏感配置,安全绝对不能忽视。这一节我说两个新手容易忽略但危害极大的问题:命名空间未授权访问漏洞和默认密钥认证绕过漏洞。

6.1 默认密钥认证绕过漏洞(CNVD-2023-17316)

这个漏洞的编号是CNVD-2023-17316,原理是:Nacos在开启鉴权后,使用了一个硬编码的默认JWT密钥。攻击者如果知道这个默认密钥,就可以自己伪造一个具有管理员权限的JWT Token,直接绕过登录认证,访问Nacos的所有接口。

我用大白话解释一下:Nacos的鉴权机制是,用户登录后由服务端签一个Token,后续请求带着这个Token,服务端验签通过就放行。验签用的"印章"是一把密钥,如果这把密钥所有人都知道(因为源码里写了默认值),那攻击者就可以自己伪造一个合法的"印章",签出一个管理员的Token,想进就进。

**这个漏洞影响范围很广,Nacos 2.x多个版本都受影响。**如果你在控制台开启了鉴权,但使用的还是默认密钥,就相当于给攻击者留了一扇虚掩的大门。

6.2 命名空间未授权访问漏洞(原理扫描)

另一个常见的风险是"namespaces未授权访问"。有的安全扫描工具会报这个漏洞,原因是Nacos开放了某些API接口(如/nacos/v1/console/namespaces),在没有正确启用鉴权或接口鉴权配置不当时,攻击者可以直接调用这些接口获取命名空间列表、服务列表等内部信息。

这种情况多发生在:部署Nacos时没有开启鉴权,或者开启了鉴权但某些特殊端口(9848、9849)的gRPC接口没有做鉴权限制。虽然很多扫描报告把这个归为"中危",但它往往是更严重攻击的前置侦察步骤——攻击者先摸清你的服务结构,再结合其他漏洞展开攻击。

6.3 开启鉴权与修改密钥实操

修复思路很简单,核心就三步:开启鉴权、修改默认密钥、重启生效。

在conf/application.properties中配置:

nacos.core.auth.enabled=true nacos.core.auth.plugin.nacos.token.secret.key=你的自定义Base64密钥 nacos.core.auth.system.type=nacos

这里要特别说的是token.secret.key的格式问题。**官方要求这个密钥必须是Base64编码的字符串,且原始长度不能少于32字节。**所以你要先随便想一个长度足够的字符串,比如:

Nacos-Security-@2024-Key-Change!QwertyuiopASDFGHJKL

然后用Base64编码一下,填入配置文件。不要直接复制上面这个字符串,它只是示例。生成Base64字符串可以用命令行:

echo -n "Nacos-Security-@2024-Key-Change!QwertyuiopASDFGHJKL" | base64

得到的输出就是你要配置的密钥。改完后重启Nacos,再登录控制台,你会发现之前直接访问某些API接口的方式已经失效了,未登录请求会被拦截。

如果你的Nacos版本低于2.2.0,建议先升级再修复漏洞,因为旧版本即使改了密钥,某些鉴权绕过链路的补丁也不完整。另外,千万不要把Nacos的管理端口直接暴露到公网,就算加了鉴权,也建议只在内网或者通过跳板机访问,这是最基础的安全意识。

7. 新手常见问题与排错经验

最后这部分,我把带新手过程中最常遇到的几个问题汇总一下,每个都是真实发生过的场景,直接给解决思路。

7.1 启动报错与版本不匹配

启动报错 "nacos Caused by: com.mysql.cj.exceptions.CJCommunicationsException":大概率是Nacos连不上MySQL。逐个排查:MySQL是否启动?账号密码是否正确?网络是否通?数据库是否初始化了表结构?

MySQL 8.4.11连接失败:这个前面提过,优先升级Nacos版本到2.5.x以上,或者创建账号时指定mysql_native_password认证插件。

Windows启动闪退:多半是JDK环境变量没配好,或者startup.cmd没加-m standalone。在命令行窗口执行而不是双击cmd文件,能直接看到报错日志。Nacos的启动日志在logs/start.out里,遇到问题先看这个文件。

服务注册成功但控制台看不到:检查命名空间和服务名。如果服务配置了namespace为dev,但控制台当前浏览的是public命名空间,当然看不到。切换命名空间看看。

7.2 配置不生效排查步骤

遇到"改了Nacos配置,项目没反应"时,按这个顺序排查:

  1. 确认服务读取的Data ID是否正确。启动日志里会打印"Loading nacos data ...",看清楚加载的是哪个Data ID。
  2. 确认命名空间是否一致。在控制台顶部能看到当前命名空间,和spring.cloud.nacos.config.namespace对比。
  3. 确认配置文件格式。Data ID以.yaml结尾,格式选YAML;以.properties结尾,格式选Properties。格式不匹配会导致解析失败。
  4. 确认是否加了@RefreshScope。加了注解才有热更新,否则需要重启。
  5. 确认Nacos配置没有语法错误。控制台编辑时注意缩进,YAML的缩进错误在运行时才会暴露,很容易被忽略。

7.3 其他实用建议

  • 版本选择策略:新项目建议直接上Nacos 2.5.x或3.x,Spring Cloud Alibaba的版本要对应好,不要混搭。可以参考Spring Cloud Alibaba官方推荐的版本对应关系,避免出现组件兼容性问题。
  • 资源和配置管理:生产环境一定要上MySQL,不要用Derby。同时开启鉴权、修改默认密码和JWT密钥。
  • 端口开放:除了8848,2.x新增的gRPC端口9848、9849如果不开,跨网络的服务调用可能间歇性失败。排查防火墙规则时别只盯着8848。
  • 配置变更记录:Nacos控制台的"历史版本"功能一定要用起来,每次配置变更都有记录,出问题可以快速回滚。我见过不少团队用Nacos很久了,还不知道有这个功能,等到配置改坏了才来找办法。

7.4 最后一个小技巧

如果是本地开发调试,Nacos未启动时Spring Boot服务启动会直接报错失败,很多人被这个坑烦过。开发阶段的解决思路是:引入Nacos依赖之前,确认Nacos服务已经启动;如果你确实需要先启动服务、再启动Nacos,可以把spring.cloud.nacos.discovery.fail-fast设为false,这样Nacos不可用时服务也能启动,虽然服务发现不会生效,但至少不影响本地代码调试。

spring: cloud: nacos: discovery: fail-fast: false

不过这个配置生产环境不建议用,生产环境Nacos挂了服务不该继续启动,否则流量打到一个没有注册信息的服务上会造成更多问题。

Nacos这个中间件,说复杂也复杂,说简单也简单。核心就是注册中心加配置中心两个能力,先把环境跑起来,再把服务注册上去,最后把配置管理玩熟,日常开发就已经够用了。后面如果项目规模上来,还可以研究Nacos集群部署、数据持久化、权限控制这些进阶能力,但那是另一个话题了。对新手来说,把这一篇的内容都跑通一遍,Nacos就算是入门了。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进