微服务注册中心帮你上户口
在单体应用时代,所有服务都挤在一起,互相调用就像同一个屋檐下喊一声那么简单。但到了微服务时代,服务被拆分成了成百上千个独立的进程,分布在不同的服务器上。这时候,一个棘手的问题出现了:我怎么知道你要找的服务在哪里?
这就好比现实生活中的派出所上户口。
1. 形象理解:老王找老六
为了讲清楚注册中心的作用,我们举个生动的例子:
场景一(无注册中心):
老王(服务消费者)想找老六(服务提供者)办事。老六买了一套房,告诉老王:“我家在翻斗花园1号楼101”。老王记住了。
过了一段时间,老六发财了,搬到了“汤臣一品A栋888”。但老王并不知道,还在往翻斗花园跑,结果自然是一头雾水,扑了个空。
痛点:服务地址变更(扩容、缩容、故障迁移)时,消费者无法及时感知,导致调用失败。场景二(有注册中心——派出所):
现在引入了派出所(注册中心)。- 服务注册(上户口):老六搬家后,第一件事是去派出所登记最新的家庭住址。
- 服务发现(查户口):老王想找老六,先去派出所询问:“老六现在住哪?”派出所告诉他最新的地址。
- 订阅通知(变更通知):老王还可以订阅老六的动态。如果老六又搬家了,派出所会第一时间通知老王:“老六搬家了,新地址是XXX”。
- 远程调用(上门办事):老王拿到最新地址后,直接上门找老六办事。
这就是微服务注册中心的核心价值:管理服务实例的动态变化,确保服务调用的高可用性。
2. 注册中心的核心工作流程
将上面的例子技术化,注册中心的工作主要包含以下四个步骤:
- **服务注册 (Service Registration)**:服务提供者(Provider)启动时,将自己的 IP、端口、服务名称等信息上报给注册中心。
- **服务发现 (Service Discovery)**:服务消费者(Consumer)向注册中心发起查询,获取可用的服务提供者列表。
- **负载均衡 (Load Balancing)**:消费者获取到列表后,利用客户端负载均衡策略(如轮询、随机)选择一个实例进行调用。
- **健康检查 (Health Check)**:注册中心会定时检查服务提供者的健康状态(心跳检测)。如果某个实例挂了,注册中心会将其从列表中剔除,防止请求打到故障节点。
3. 为什么我们选择 Nacos?
市面上的注册中心琳琅满目,主流的包括 Netflix Eureka、HashiCorp Consul、Apache Zookeeper 以及 Alibaba Nacos。为什么在 Spring Cloud Alibaba 体系中,要在“慕聘网”项目中选择 Nacos 呢?

我们从CAP理论和功能特性两个维度进行对比:
| 注册中心 | CAP 模型 | 维护状态 | 从属生态 | 核心优势 | 劣势 |
|---|---|---|---|---|---|
| Netflix Eureka | AP (高可用) | 停止维护 | Spring Cloud Netflix | 模型简单,适合早期微服务 | 已停止更新,界面简陋 |
| Zookeeper | CP (强一致) | 活跃 | Hadoop/Dubbo | 强一致性,选举期间不可用 | 不适合大规模服务发现(CP导致可用性降低) |
| Consul | CP (强一致) | 活跃 | HashiCorp/Go | 支持多数据中心,带KV存储 | 也是CP模型,Spring Cloud集成稍弱 |
| Alibaba Nacos | AP / CP (可切换) | 非常活跃 | Spring Cloud Alibaba | 集注册中心与配置中心于一体,模型切换灵活,社区活跃,中文文档完善 | 极少 |
核心理由:
- AP/CP 灵活切换:Nacos 是唯一支持 AP 和 CP 模式切换的注册中心。对于大多数服务发现场景(如我们的招聘业务),我们更看重**可用性 (AP)**,即允许短暂的数据不一致,也要保证服务能被调用。
- 双剑合璧:Nacos 同时支持服务注册和配置管理,这让我们少部署一套中间件(省去了 Config Server + Bus),降低了运维复杂度。
- 生态亲和性:作为 Spring Cloud Alibaba 的核心组件,Nacos 与 Sentinel、Dubbo 等组件的集成天衣无缝。
因此,Nacos 是我们构建“慕聘网”微服务架构的不二之选。
Docker安装配置Nacos
注册中心是微服务架构中的“通讯录”,是服务发现的核心。虽然 Nacos 支持多种安装方式(如源码构建、压缩包解压),但 Docker 无疑是最便捷、最适合开发环境的选择。
本节我们将演示如何通过 Docker 快速部署一个单机版的 Nacos Server。
1. 拉取镜像
首先,我们在 Docker Hub 上搜索 Nacos 的官方镜像。为了保持与课程一致性和稳定性,我们选择 2.1.1 版本。
打开终端,执行以下命令拉取镜像:
1 | docker pull nacos/nacos-server:2.1.1 |
2. 启动容器
Nacos 默认以集群模式(Cluster)启动,但在开发环境中,我们通常只需要单机模式(Standalone)。因此,在启动时必须指定 MODE=standalone 环境变量。
此外,为了防止 Nacos 占用过多内存(默认 JVM 参数较大),我们建议限制其 JVM 内存参数。
执行以下命令启动容器:
1 | docker run -d \ |
-d: 后台运行。-p 8848:8848: 映射主端口,用于访问控制台和客户端注册。-p 9848/9849: Nacos 2.x 新增的 gRPC 端口,务必映射,否则客户端无法连接。-e MODE=standalone: 关键! 指定单机模式启动,否则默认集群模式会报错。-e JVM_XMS/XMX: 限制堆内存为 256M,避免撑爆开发机内存。
启动后,使用 docker ps 检查容器状态:
1 | docker ps | grep nacos |
3. 访问控制台
容器启动成功后,打开浏览器访问:http://localhost:8848/nacos。
你将看到如下登录界面:

- 默认账号:
nacos - 默认密码:
nacos
4. 关键配置与监控
登录成功后,你可以看到 Nacos 的管理主页。
修改默认密码
为了安全起见,强烈建议在生产环境中修改默认密码。点击右上角的用户名 -> “修改密码”即可。
资源监控
Nacos 是一个 Java 应用,可能会占用一定的 CPU 和内存。我们可以使用 Docker 自带的监控命令查看其资源使用情况:
1 | docker stats nacos-quick |
如果发现内存占用过高,可以适当调整启动命令中的 JVM 参数。
至此,我们的 Nacos 注册中心已经准备就绪,接下来就可以开始微服务的改造了!
微服务节点整合Nacos
Nacos 服务端就绪后,接下来我们将微服务节点整合进 Nacos,实现服务的自动注册与发现。
我们主要涉及三个步骤:引入依赖 -> 修改配置 -> 开启注解。
1. 引入依赖 (Add Dependency)
由于我们的项目是多模块架构,建议将 Nacos 的客户端依赖添加到公共模块 hire-common 中,这样其他业务微服务(如 service-user, service-company)只需要依赖 hire-common 即可,无需重复引入。
在 hire-common/pom.xml 中添加:
1 | <!-- 引入nacos注册中心 --> |
注意:我们需要在父工程中管理
spring-cloud-alibaba-dependencies的版本,确保版本兼容性。
2. 添加配置 (Add Configuration)
以 service-user(用户服务)为代表。我们需要在 application.yml(或 bootstrap.yml)中告诉微服务 Nacos 的地址。
1 | spring: |
同理,我们在 service-company(企业服务)中也进行类似的配置,只需将 spring.application.name 修改为 company-service。
3. 开启注解 (Enable Annotation)
最后一步,在微服务的启动类 Application.java 上添加 @EnableDiscoveryClient 注解,开启服务发现功能。
1 |
|
4. 验证结果 (Verification)
启动 service-user 和 service-company 两个微服务。启动成功后,刷新 Nacos 控制台的“服务列表”页面。

我们可以清晰地看到:
- 服务名:
user-service和company-service已经成功注册。 - 实例数:显示了当前在线的服务实例数量。
- 健康状态:如果服务挂掉或者网络不通,Nacos 会将其标记为不健康,随后将其剔除。
至此,我们的微服务已经成功拿到了“户口”,可以进行下一步的服务间调用了!
构建多实例集群
在微服务架构中,为了保证高可用,通常会部署同一个服务的多个实例,形成集群。在开发本地调试时,我们也可以模拟这种集群环境。
1. 动态端口配置
为了能够在同一台机器上启动多个实例,我们需要确保每个实例占用不同的端口。
观察 service-user 的 application.yml 配置文件:
1 | server: |
这里使用了 ${port:10024} 的语法。意思是:尝试读取名为 port 的环境变量或系统属性;如果没有读取到,则默认使用 10024 端口。
这为我们启动多实例奠定了基础。
2. IDEA 启动多实例
以 IntelliJ IDEA 为例,演示如何启动第二个 user-service 实例:
- 复制配置:点击右上角的启动配置下拉框 -> “Edit Configurations”。找到
Application(user-service),点击左上角的复制图标(Copy Configuration)。 - 修改名称:将新配置命名为
Application-10034(方便区分)。 - 添加 VM Options:在 “Build and run” 的 “VM options” 输入框中添加:
-Dport=10034 - 启动:保存配置并启动这个新实例。
此时,我们本地就运行了两个 user-service 实例,端口分别为 10024 (默认) 和 10034 (新启动)。
3. 验证集群
刷新 Nacos 控制台的“服务列表”。
你将看到 user-service 的 实例数 变成了 2。点击对应的“详情”按钮,可以看到两个实例的 IP 和端口信息(10024 和 10034)。
此时,当其他服务调用 user-service 时,Nacos 结合负载均衡器(如 LoadBalancer)就会自动将请求分发到这两个实例上,实现了负载均衡。同时,如果其中一个实例挂掉,流量会自动切换到另一个实例,实现了高可用。
Nacos管理微服务配置
在微服务架构中,随着服务数量的增加,配置文件的管理变得越来越复杂。如果不使用配置中心,我们面临着两个主要痛点:
- 配置冗余:多个微服务可能包含相同的配置(如 Redis、RabbitMQ),每次修改都需要逐个文件修改,极易出错。
- 动态更新困难:修改了配置文件后,通常需要重启服务才能生效,这在生产环境中是不可接受的。
Nacos 配置中心 正是为了解决这些问题而生。它允许我们将配置从代码中分离出来,集中管理,并且支持秒级热更新。
1. 引入依赖
在 hire-common 模块中,我们已经引入了 Nacos Config 的依赖(注意:它和 Nacos Discovery 是两个不同的 starter):
1 | <!-- 引入nacos配置中心 --> |
2. 创建 bootstrap.yml
Spring Cloud 启动时会优先加载 bootstrap.yml,然后才是 application.yml。因为我们需要从 Nacos 拉取配置,所以 Nacos 的连接信息必须配置在 bootstrap.yml 中。
在 service-user 的 src/main/resources 下创建 bootstrap.yml:
1 | spring: |
3. 在 Nacos 中创建配置
登录 Nacos 控制台,进入“配置管理” -> “配置列表”,点击右上角的“+”号新增配置。
- Data ID: 命名规则通常为
${spring.application.name}-${spring.profiles.active}.${file-extension}。例如:user-service-dev.yaml。 - Group: 默认为
DEFAULT_GROUP。 - 配置内容: 将原
application-dev.yml中的内容(如 Redis、RabbitMQ 连接信息)粘贴进去。
例如,我们将 Redis 的配置迁移到 Nacos:
1 | spring: |

4. 动态刷新
Nacos 的一大亮点是支持动态刷新。在 controller 类上添加 @RefreshScope 注解,或者在 extension-configs 中配置 refresh: true,当我们在 Nacos 控制台修改配置并发布后,微服务会自动感知并更新配置,无需重启!
这极大地提高了运维效率和系统的灵活性。