1 为什么需要注册中心?
服务注册中心在微服务架构中起到核心的作用,它能够解耦服务提供者与服务消费者,因为在一个微服务架构中,服务提供者的数量和分布是动态且不可预测的。传统的静态负载均衡机制在这种情况下显得不再适用,因此需要引入服务注册中心来管理这些动态变化。
Nacos 通过提供简单易用的动态服务发现、服务配置、服务共享与管理等服务基础设施,帮助用户在云原生时代,在私有云、混合云或者公有云等所有云环境中,更好的构建、交付、管理自己的微服务平台,更快的复用和组合业务服务,更快的交付商业创新的价值,从而为用户赢得市场。
2 springcloud与nacos的版本兼容对照表
请参阅我的博客《Spring Cloud2024.x实战 | nacos系列 | 第2篇: springcloud整合配置中心nacos2.5.1》。
3 注册中心原理
在开始搭建 Nacos Discovery 的示例之前,我们先来简单了解下注册中心的原理。
在使用注册中心时,一共有三种角色:服务提供者(Service Provider)、服务消费者(Service Consumer)、注册中心(Registry)。
在一些文章中,服务提供者被称为 Server,服务消费者被称为 Client。胖友们知道即可。
三个角色交互如下图所示:
① Provider:
- 启动时,向 Registry 注册自己为一个服务(Service)的实例(Instance)。
- 同时,定期向 Registry 发送心跳,告诉自己还存活。
- 关闭时,向 Registry 取消注册。
② Consumer:
- 启动时,向 Registry 订阅使用到的服务,并缓存服务的实例列表在内存中。
- 后续,Consumer 向对应服务的 Provider 发起调用时,从内存中的该服务的实例列表选择一个,进行远程调用。
- 关闭时,向 Registry 取消订阅。
③ Registry:
- Provider 超过一定时间未心跳时,从服务的实例列表移除。
- 服务的实例列表发生变化(新增或者移除)时,通知订阅该服务的 Consumer,从而让 Consumer 能够刷新本地缓存。
当然,不同的注册中心可能在实现原理上会略有差异。例如说,Eureka 注册中心,并不提供通知功能,而是 Eureka Client 自己定期轮询,实现本地缓存的更新。
另外,Provider 和 Consumer 是角色上的定义,一个服务同时即可以是 Provider 也可以作为 Consumer。例如说,优惠劵服务可以给订单服务提供接口,同时又调用用户服务提供的接口。
4 快速入门
示例代码对应仓库:
- 服务提供者:
sca-nacos-discovery-demo01-provider
- 服务消费者:
sca-nacos-discovery-demo01-consumer
本小节,我们来搭建一个 Nacos Discovery 组件的快速入门示例。步骤如下:
- 首先,搭建一个服务提供者
demo-provider
,注册服务到 Nacos 中。 - 然后,搭建一个服务消费者
demo-consumer
,从 Nacos 获取到demo-provider
服务的实例列表,选择其中一个示例,进行 HTTP 远程调用。
4.1 搭建服务提供者
创建sca-nacos-discovery-demo01-provider
项目,作为服务提供者 demo-provider
。最终项目代码如下图所示:
4.1.1 引入依赖
在pom.xml
文件中,主要引入 Spring Cloud Nacos Discovery 相关依赖。代码如下:
<properties>
<spring.boot.version>3.4.4</spring.boot.version>
<spring.cloud.version>2024.0.1</spring.cloud.version>
<spring.cloud.alibaba.version>2023.0.1.2</spring.cloud.alibaba.version>
</properties>
<!--
引入 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,进行依赖版本的管理,防止不兼容。
在 https://dwz.cn/mcLIfNKt 文章中,Spring Cloud Alibaba 开发团队推荐了三者的依赖关系
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>