不会飞的章鱼

熟能生巧,勤能补拙,静能养慧;为而不争,莫向外求,反求诸己;念念不忘,必有回响

【慕聘网】微服务注册中心Nacos

微服务注册中心帮你上户口

在单体应用时代,所有服务都挤在一起,互相调用就像同一个屋檐下喊一声那么简单。但到了微服务时代,服务被拆分成了成百上千个独立的进程,分布在不同的服务器上。这时候,一个棘手的问题出现了:我怎么知道你要找的服务在哪里?

这就好比现实生活中的派出所上户口

1. 形象理解:老王找老六

为了讲清楚注册中心的作用,我们举个生动的例子:

  • 场景一(无注册中心)
    老王(服务消费者)想找老六(服务提供者)办事。老六买了一套房,告诉老王:“我家在翻斗花园1号楼101”。老王记住了。
    过了一段时间,老六发财了,搬到了“汤臣一品A栋888”。但老王并不知道,还在往翻斗花园跑,结果自然是一头雾水,扑了个空。
    痛点:服务地址变更(扩容、缩容、故障迁移)时,消费者无法及时感知,导致调用失败。

  • 场景二(有注册中心——派出所)
    现在引入了派出所(注册中心)

    1. 服务注册(上户口):老六搬家后,第一件事是去派出所登记最新的家庭住址。
    2. 服务发现(查户口):老王想找老六,先去派出所询问:“老六现在住哪?”派出所告诉他最新的地址。
    3. 订阅通知(变更通知):老王还可以订阅老六的动态。如果老六又搬家了,派出所会第一时间通知老王:“老六搬家了,新地址是XXX”。
    4. 远程调用(上门办事):老王拿到最新地址后,直接上门找老六办事。

这就是微服务注册中心的核心价值:管理服务实例的动态变化,确保服务调用的高可用性。

2. 注册中心的核心工作流程

将上面的例子技术化,注册中心的工作主要包含以下四个步骤:

  1. **服务注册 (Service Registration)**:服务提供者(Provider)启动时,将自己的 IP、端口、服务名称等信息上报给注册中心。
  2. **服务发现 (Service Discovery)**:服务消费者(Consumer)向注册中心发起查询,获取可用的服务提供者列表。
  3. **负载均衡 (Load Balancing)**:消费者获取到列表后,利用客户端负载均衡策略(如轮询、随机)选择一个实例进行调用。
  4. **健康检查 (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 集注册中心与配置中心于一体,模型切换灵活,社区活跃,中文文档完善 极少

核心理由

  1. AP/CP 灵活切换:Nacos 是唯一支持 AP 和 CP 模式切换的注册中心。对于大多数服务发现场景(如我们的招聘业务),我们更看重**可用性 (AP)**,即允许短暂的数据不一致,也要保证服务能被调用。
  2. 双剑合璧:Nacos 同时支持服务注册配置管理,这让我们少部署一套中间件(省去了 Config Server + Bus),降低了运维复杂度。
  3. 生态亲和性:作为 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
2
3
4
5
6
7
8
9
docker run -d \
--name nacos-quick \
-e MODE=standalone \
-e JVM_XMS=256m \
-e JVM_XMX=256m \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
nacos/nacos-server:2.1.1
  • -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
  • 默认密码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
2
3
4
5
<!-- 引入nacos注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

注意:我们需要在父工程中管理 spring-cloud-alibaba-dependencies 的版本,确保版本兼容性。

2. 添加配置 (Add Configuration)

service-user(用户服务)为代表。我们需要在 application.yml(或 bootstrap.yml)中告诉微服务 Nacos 的地址。

1
2
3
4
5
6
7
spring:
application:
name: user-service # 服务名称,极为重要,将作为服务ID注册到Nacos
cloud:
nacos:
discovery:
server-addr: 192.168.1.121:8848 # Nacos服务端地址

同理,我们在 service-company(企业服务)中也进行类似的配置,只需将 spring.application.name 修改为 company-service

3. 开启注解 (Enable Annotation)

最后一步,在微服务的启动类 Application.java 上添加 @EnableDiscoveryClient 注解,开启服务发现功能。

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableDiscoveryClient // 开启注册中心的服务注册和发现功能
@MapperScan(basePackages = "com.imooc.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

4. 验证结果 (Verification)

启动 service-userservice-company 两个微服务。启动成功后,刷新 Nacos 控制台的“服务列表”页面。

Nacos服务列表

我们可以清晰地看到:

  • 服务名user-servicecompany-service 已经成功注册。
  • 实例数:显示了当前在线的服务实例数量。
  • 健康状态:如果服务挂掉或者网络不通,Nacos 会将其标记为不健康,随后将其剔除。

至此,我们的微服务已经成功拿到了“户口”,可以进行下一步的服务间调用了!

构建多实例集群

在微服务架构中,为了保证高可用,通常会部署同一个服务的多个实例,形成集群。在开发本地调试时,我们也可以模拟这种集群环境。

1. 动态端口配置

为了能够在同一台机器上启动多个实例,我们需要确保每个实例占用不同的端口。

观察 service-userapplication.yml 配置文件:

1
2
server:
port: ${port:10024}

这里使用了 ${port:10024} 的语法。意思是:尝试读取名为 port 的环境变量或系统属性;如果没有读取到,则默认使用 10024 端口。

这为我们启动多实例奠定了基础。

2. IDEA 启动多实例

以 IntelliJ IDEA 为例,演示如何启动第二个 user-service 实例:

  1. 复制配置:点击右上角的启动配置下拉框 -> “Edit Configurations”。找到 Application (user-service),点击左上角的复制图标(Copy Configuration)。
  2. 修改名称:将新配置命名为 Application-10034 (方便区分)。
  3. 添加 VM Options:在 “Build and run” 的 “VM options” 输入框中添加:
    -Dport=10034
  4. 启动:保存配置并启动这个新实例。

此时,我们本地就运行了两个 user-service 实例,端口分别为 10024 (默认) 和 10034 (新启动)。

3. 验证集群

刷新 Nacos 控制台的“服务列表”。

你将看到 user-service实例数 变成了 2。点击对应的“详情”按钮,可以看到两个实例的 IP 和端口信息(10024 和 10034)。

此时,当其他服务调用 user-service 时,Nacos 结合负载均衡器(如 LoadBalancer)就会自动将请求分发到这两个实例上,实现了负载均衡。同时,如果其中一个实例挂掉,流量会自动切换到另一个实例,实现了高可用

Nacos管理微服务配置

在微服务架构中,随着服务数量的增加,配置文件的管理变得越来越复杂。如果不使用配置中心,我们面临着两个主要痛点:

  1. 配置冗余:多个微服务可能包含相同的配置(如 Redis、RabbitMQ),每次修改都需要逐个文件修改,极易出错。
  2. 动态更新困难:修改了配置文件后,通常需要重启服务才能生效,这在生产环境中是不可接受的。

Nacos 配置中心 正是为了解决这些问题而生。它允许我们将配置从代码中分离出来,集中管理,并且支持秒级热更新。

1. 引入依赖

hire-common 模块中,我们已经引入了 Nacos Config 的依赖(注意:它和 Nacos Discovery 是两个不同的 starter):

1
2
3
4
5
6
7
8
9
10
<!-- 引入nacos配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud 2.4+ 需要引入 bootstrap 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

2. 创建 bootstrap.yml

Spring Cloud 启动时会优先加载 bootstrap.yml,然后才是 application.yml。因为我们需要从 Nacos 拉取配置,所以 Nacos 的连接信息必须配置在 bootstrap.yml 中。

service-usersrc/main/resources 下创建 bootstrap.yml

1
2
3
4
5
6
7
8
9
10
11
spring:
application:
name: user-service
cloud:
nacos:
config:
server-addr: 192.168.1.121:8848 # Nacos 配置中心地址
file-extension: yaml # 配置文件格式
extension-configs: # 扩展配置,用于共享配置(如 redis, rabbitmq)
- data-id: common.yaml
refresh: true

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
2
3
4
5
spring:
redis:
host: 192.168.1.121
port: 6379
password: your_password

Nacos配置列表

4. 动态刷新

Nacos 的一大亮点是支持动态刷新。在 controller 类上添加 @RefreshScope 注解,或者在 extension-configs 中配置 refresh: true,当我们在 Nacos 控制台修改配置并发布后,微服务会自动感知并更新配置,无需重启!

这极大地提高了运维效率和系统的灵活性。

------ 本文结束------
如果你喜欢这篇文章,打赏一下让我开心到原地转圈圈~,金额随意,感谢鼓励与支持!