Nacos 从入门到生产落地
一、为什么我们需要 Nacos?
在讲 Nacos 之前,我们先搞清楚微服务架构下的两个核心痛点。
痛点 1:服务发现问题
在单体架构中,服务之间的调用就是本地方法调用,非常简单。但在微服务架构中,一个系统被拆分成了几十个甚至上百个服务,每个服务都部署在多个节点上。
这时候就出现了一个问题:服务 A 如何知道服务 B 的所有实例地址?
如果没有注册中心,你只能在配置文件中写死服务 B 的所有地址。但当服务 B 扩容、缩容、节点宕机时,你需要手动修改所有依赖服务 B 的配置文件,这在微服务架构下是完全不可行的。
痛点 2:配置管理问题
每个微服务都有自己的配置文件,当服务数量越来越多时,配置管理就变成了一场灾难:
- 配置分散在各个服务中,难以统一管理
- 修改配置需要重新打包、部署、重启服务
- 不同环境(开发、测试、生产)的配置难以隔离
- 配置变更没有版本控制,出了问题无法回滚
而 Nacos 就是为了解决这两个痛点而生的。它是一个集服务注册发现、配置管理、服务治理于一体的开源平台,由阿里巴巴开源,是 Spring Cloud Alibaba 生态的核心组件。
Nacos 的核心优势
- 一站式解决方案:同时提供注册中心和配置中心功能,不需要部署多个组件
- 简单易用:提供 Web 管理界面,操作简单,一分钟就能上手
- 高可用:支持集群部署,保证服务的高可用性
- 动态配置:配置修改后实时生效,不需要重启服务
- 丰富的服务治理功能:支持服务权重、负载均衡、熔断降级、流量控制等
- 多语言支持:支持 Java、Go、Python、Node.js 等多种语言
二、Nacos 核心概念
要真正用好 Nacos,必须先搞懂它的核心概念。
1. 命名空间(Namespace)
命名空间是 Nacos 中最高级别的隔离单元,用于隔离不同环境的配置和服务。比如你可以创建三个命名空间:dev(开发环境)、test(测试环境)、prod(生产环境),不同命名空间之间的配置和服务完全隔离。
2. 分组(Group)
分组是命名空间下的二级隔离单元,用于将不同的服务或配置进行分组管理。比如你可以将同一个项目的所有服务和配置都放在同一个分组下。
3. 服务(Service)
服务是微服务架构中的基本单元,对应一个应用程序。每个服务都有一个唯一的名称,比如user-service、order-service。
4. 实例(Instance)
实例是服务的一个具体运行节点,对应一个 JVM 进程。每个实例都有自己的 IP 地址、端口号和健康状态。
5. 集群(Cluster)
集群是服务下的实例分组,用于将同一个服务的不同实例进行分组管理。比如你可以将user-service的实例分为北京集群和上海集群,实现地域级别的服务调用。
6. 配置(Config)
配置是 Nacos 中存储的键值对数据,对应应用程序的配置文件。每个配置都有一个唯一的标识:Data ID + Group + Namespace。
三、Nacos 核心功能一:服务注册与发现
服务注册与发现是 Nacos 最基础也是最核心的功能。它解决了微服务之间如何相互发现和调用的问题。
3.1 服务注册流程
当一个服务启动时,它会向 Nacos 服务器发送一个注册请求,将自己的服务信息(服务名、IP 地址、端口号、健康状态等)注册到 Nacos 中。
Nacos 收到注册请求后,会将这个服务实例的信息存储到自己的注册表中。同时,Nacos 会向所有订阅了这个服务的客户端推送最新的服务列表。
3.2 心跳机制与健康检查
服务注册到 Nacos 后,需要定期向 Nacos 发送心跳包,证明自己还活着。默认情况下,心跳间隔是 5 秒。
如果 Nacos 在 15 秒内没有收到某个实例的心跳包,就会将这个实例标记为不健康。如果在 30 秒内还没有收到心跳包,就会将这个实例从注册表中删除。
3.3 服务发现流程
当服务 A 需要调用服务 B 时,它会向 Nacos 发送一个服务发现请求,获取服务 B 的所有健康实例列表。
Nacos 会将服务 B 的实例列表返回给服务 A,服务 A 会将这个列表缓存到本地。然后服务 A 会根据负载均衡策略,选择一个实例进行调用。
为了保证服务列表的实时性,服务 A 会定期(默认 30 秒)向 Nacos 拉取最新的服务列表。同时,当服务 B 的实例发生变化时,Nacos 也会主动推送最新的服务列表给服务 A。
四、Nacos 核心功能二:动态配置中心
动态配置中心是 Nacos 另一个非常重要的功能。它解决了微服务架构下配置管理的痛点,实现了配置的统一管理、动态更新和版本控制。
4.1 配置发布与同步流程
- 运维人员在 Nacos 管理界面发布或修改配置
- Nacos 将配置更新到自己的数据库中
- Nacos 向所有订阅了这个配置的客户端推送配置更新通知
- 客户端收到通知后,从 Nacos 拉取最新的配置
- 客户端更新本地缓存的配置,应用程序使用最新的配置
整个过程不需要重启服务,配置修改后实时生效。
4.2 动态配置刷新原理
Nacos 提供了两种配置刷新方式:
- 自动刷新:在
@Value注解上加上@RefreshScope注解,当配置发生变化时,会自动刷新字段的值 - 监听刷新:通过
ConfigService添加配置监听器,当配置发生变化时,会触发监听器的回调方法
自动刷新示例:
java
运行
@RestController
@RefreshScope // 开启自动刷新
public class ConfigController {
@Value("${config.info:默认值}")
private String configInfo;
@GetMapping("/config")
public String getConfigInfo() {
return configInfo;
}
}
4.3 配置版本控制与回滚
Nacos 会自动保存配置的历史版本,每次修改配置都会生成一个新的版本号。如果配置修改后出现问题,可以一键回滚到之前的任意版本,非常方便。
五、Spring Boot 整合 Nacos 完整教程
下面我就以 Spring Boot 2.7.x 为例,教你如何快速整合 Nacos 的服务注册发现和配置中心功能。
第一步:引入依赖
xml
<!-- Spring Cloud Alibaba Nacos 服务注册发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Nacos 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
第二步:配置 Nacos
在bootstrap.yml中添加 Nacos 配置(注意:必须是bootstrap.yml,不能是application.yml):
yaml
spring:
application:
name: user-service # 服务名称,必须配置
cloud:
nacos:
# 服务注册发现配置
discovery:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: dev # 命名空间
group: DEFAULT_GROUP # 分组
# 配置中心配置
config:
server-addr: 127.0.0.1:8848
namespace: dev
group: DEFAULT_GROUP
file-extension: yaml # 配置文件格式
# 共享配置
shared-configs:
- data-id: common-config.yaml
group: DEFAULT_GROUP
refresh: true # 开启自动刷新
第三步:开启服务注册发现
在启动类上添加@EnableDiscoveryClient注解:
java
运行
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
现在,你的服务启动后就会自动注册到 Nacos 中了。
第四步:使用 OpenFeign 进行服务调用
Nacos 整合 OpenFeign 非常简单,只需要三步:
- 引入 OpenFeign 依赖:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 在启动类上添加
@EnableFeignClients注解:
java
运行
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
- 编写 Feign 接口:
java
运行
@FeignClient(name = "order-service") // 服务名称,对应 Nacos 中的服务名
public interface OrderFeignClient {
@GetMapping("/order/{userId}")
List<Order> getOrdersByUserId(@PathVariable Long userId);
}
现在,你就可以在代码中注入这个接口,像调用本地方法一样调用远程服务了:
java
运行
@Service
public class UserService {
@Autowired
private OrderFeignClient orderFeignClient;
public User getUserWithOrders(Long userId) {
User user = userMapper.selectById(userId);
// 调用远程服务
List<Order> orders = orderFeignClient.getOrdersByUserId(userId);
user.setOrders(orders);
return user;
}
}
六、Nacos 高可用集群部署
生产环境中,绝对不能使用单机 Nacos,否则 Nacos 挂了,整个微服务系统都会瘫痪。Nacos 支持集群部署,官方推荐至少部署 3 个节点,组成一个高可用集群。
6.1 Nacos 集群架构
Nacos 集群采用 "一主多从" 的架构,所有节点都是对等的,没有主从之分。客户端可以连接任意一个节点,所有节点之间会自动同步数据。
Nacos 集群依赖 MySQL 数据库来存储配置和服务数据,所有节点都连接同一个 MySQL 数据库(或 MySQL 集群)。
6.2 集群部署步骤
- 准备 3 台服务器:192.168.1.10、192.168.1.11、192.168.1.12
- 安装 MySQL 数据库:创建数据库
nacos,执行 Nacos 提供的 SQL 脚本初始化数据库 - 下载 Nacos 安装包:在 3 台服务器上都下载并解压 Nacos
- 修改配置文件:修改每台服务器上的
conf/application.properties文件,配置数据库连接信息 - 配置集群节点:在每台服务器上创建
conf/cluster.conf文件,写入所有节点的地址:plaintext
192.168.1.10:8848 192.168.1.11:8848 192.168.1.12:8848 - 启动 Nacos:在每台服务器上执行
bin/startup.sh启动 Nacos - 配置负载均衡:在 Nginx 中配置反向代理,将请求转发到 3 个 Nacos 节点上
现在,你就拥有了一个高可用的 Nacos 集群了。客户端只需要配置 Nginx 的地址,就可以访问集群了。
七、生产环境常见坑与最佳实践
坑 1:配置不生效
常见原因:
- 配置文件格式错误
- Data ID、Group、Namespace 不匹配
- 没有开启自动刷新
- 配置优先级问题
解决方案:
- 检查配置文件格式是否正确
- 确保 Data ID、Group、Namespace 与代码中的配置一致
- 在需要自动刷新的类上添加
@RefreshScope注解 - 了解 Nacos 配置的优先级规则,避免配置被覆盖
坑 2:服务注册不上
常见原因:
- Nacos 服务器地址配置错误
- 防火墙或安全组没有开放 8848 端口
- 服务名称配置错误
- 网络不通
解决方案:
- 检查 Nacos 服务器地址是否正确
- 开放 8848 端口和集群通信端口
- 确保服务名称唯一且正确
- 测试网络连通性
坑 3:服务调用失败
常见原因:
- 服务提供者没有注册到 Nacos
- 服务消费者没有获取到最新的服务列表
- 负载均衡策略配置错误
- 服务提供者宕机
解决方案:
- 检查服务提供者是否正常注册
- 检查服务消费者的服务列表是否正确
- 配置合理的负载均衡策略
- 开启服务健康检查和自动剔除
坑 4:Nacos 内存溢出
常见原因:
- 服务数量太多,实例数量太大
- 配置数量太多,历史版本太多
- JVM 堆内存设置太小
解决方案:
- 合理设置 JVM 堆内存大小,建议至少 2G
- 定期清理无用的服务和配置
- 开启配置历史版本自动清理
最佳实践
- 使用命名空间隔离环境:开发、测试、生产环境使用不同的命名空间
- 使用分组管理项目:同一个项目的所有服务和配置放在同一个分组下
- 配置合理的心跳间隔:默认 5 秒,生产环境可以适当调整
- 开启配置自动刷新:对于需要动态更新的配置,一定要开启自动刷新
- 定期备份配置:定期导出 Nacos 配置,防止数据丢失
- 监控 Nacos 状态:监控 Nacos 集群的健康状态、内存使用率、CPU 使用率等指标
- 限制配置大小:单个配置文件不要超过 100KB,大配置建议拆分
- 不要在配置中存储敏感信息:敏感信息(如数据库密码)应该加密存储
更多推荐




所有评论(0)