跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Spring Cloud 服务注册与服务发现

综述由AI生成介绍微服务架构下的服务注册与发现机制,基于 CAP 理论分析注册中心选型,详细演示了 Eureka Server 搭建、服务提供者注册及服务消费者通过 DiscoveryClient 实现远程调用的完整流程,并对比了 Eureka 与 Zookeeper 的差异。

微码行者发布于 2026/3/26更新于 2026/5/309.4K 浏览
Spring Cloud 服务注册与服务发现

一、背景

1.1、问题描述

在微服务架构中,远程调用时 URL 通常是写死的。例如:

String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();

当更换机器或新增机器时,这个 URL 就需要跟着变更,需要通知所有的相关服务去修改。随之而来的就是各个项目的配置文件反复更新,各个项目的频繁部署。这种没有具体意义但又不得不做的工作,会让人非常痛苦。

1.2、解决思路

生活中,避免不了和各个机构(医院、学校、政府部门等)打交道,就需要保存各个机构的电话号码。如果机构换了电话号码,就需要通知各个使用方,但是这些机构的使用方群体是巨大的,没办法做到一一通知,怎么处理呢?

机构电话如果发生变化,通知 114。用户需要联系机构时,先打 114 查询电话,然后再联系各个机构。114 查号台的作用主要有两个:

  • 号码注册:服务方把电话上报给 114
  • 号码查询:使用方通过 114 可以查到对应的号码

同样的,微服务开发时,也可以采用类似的方案。

  • 服务启动/变更时,向注册中心报道。注册中心记录应用和 IP 的关系。
  • 调用方调用时,先去注册中心获取服务方的 IP,再去服务方进行调用。

1.3、什么是注册中心?

在最初的架构体系中,集群的概念还不那么流行,且机器数量也比较少,此时直接使用 DNS+Nginx 就可以满足几乎所有服务的发现。相关的注册信息直接配置在 Nginx。但是随着微服务的流行与流量的激增,机器规模逐渐变大,并且机器会有频繁的上下线行为,这种时候需要运维手动地去维护这个配置信息是一个很难的操作。所以开发者们开始希望有这么一个东西,它能维护一个服务列表,哪个机器上线了,哪个机器宕机了,这些信息都会自动更新到服务列表上,客户端拿到这个列表,直接进行服务调用即可。这就是注册中心。

注册中心主要有三种角色:

  • 服务提供者 (Server):一次业务中,被其它微服务调用的服务。也就是提供接口给其它微服务。
  • 服务消费者 (Client):一次业务中,调用其它微服务的服务。也就是调用其它微服务提供的接口。
  • 服务注册中心 (Registry):用于保存 Server 的注册信息,当 Server 节点发生变更时,Registry 会同步变更。服务与注册中心使用一定机制通信,如果注册中心与某服务长时间无法通信,就会注销该实例。

他们之间的关系以及工作内容,可以通过两个概念来描述:

  • 服务注册:服务提供者在启动时,向 Registry 注册自身服务,并向 Registry 定期发送心跳汇报存活状态。
  • 服务发现:服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口。服务发现的一个重要作用就是提供给服务消费者一个可用的服务列表。

1.4、CAP 理论

谈到注册中心,就避不开 CAP 理论。 CAP 理论是分布式系统设计中最基础,也是最为关键的理论。

  • 一致性 (Consistency):CAP 理论中的一致性,指的是强一致性。所有节点在同一时间具有相同的数据。
  • 可用性 (Availability):保证每个请求都有响应(响应结果可能不对)。
  • 分区容错性 (Partition Tolerance):当出现网络分区后,系统仍然能够对外提供服务。

举例说明:

一个部门全国各地都有岗位,这时候,总部下发了一个通知,由于通知需要开会周知全员,当有客户咨询时:

  1. 所有成员对客户的回应结果都是一致的(一致性)
  2. 客户咨询时,一定有回应(可用性)
  3. 当其中一个成员休假时,这个部门的其他成员也可以对客户提供咨询服务(分区容错性)

CAP 理论告诉我们:一个分布式系统不可能同时满足数据一致性、服务可用性和分区容错性这三个基本需求,最多只能同时满足其中的两个。

在分布式系统中,系统间的网络不能 100% 保证健康,服务又必须对外保证服务。因此 Partition Tolerance 不可避免。那就只能在 C 和 A 中选择一个。也就是 CP 或者 AP 架构。

正常情况: 架构图

网络异常: 网络异常图

CP 架构:为了保证分布式系统对外的数据一致性,于是选择不返回任何数据。 AP 架构:为了保证分布式系统的可用性,节点 2 返回 V0 版本的数据(即使这个数据不正确)。

1.5、常见的注册中心

  1. Zookeeper:Zookeeper 的官方并没有说它是一个注册中心,但是国内 Java 体系,大部分的集群环境都是依赖 Zookeeper 来完成注册中心的功能。
  2. Eureka:Eureka 是 Netflix 开发的基于 REST 的服务发现框架,主要用于服务注册,管理,负载均衡和服务故障转移。官方声明在 Eureka 2.0 版本停止维护,不建议使用。但是 Eureka 是 SpringCloud 服务注册/发现的默认实现,所以目前还是有很多公司在使用。
  3. Nacos:Nacos 是 Spring Cloud Alibaba 架构中重要的组件,除了服务注册,服务发现功能之外,Nacos 还支持配置管理,流量管理,DNS,动态 DNS 等多种特性。

CAP 理论对比:

ZookeeperEurekaNacos
CAP 理论CPAPCP 或 AP、默认 AP

在分布式环境中,即使拿到一个错误的数据,也胜过无法提供实例信息而造成请求失败要好(比如淘宝 11.11,京东 618 都是谨遵 AP 原则),本系列文章会给大家介绍 Eureka 和 Nacos 的使用。

二、Eureka 介绍

Eureka 是 Netflix OSS 套件中关于服务注册和发现的解决方案。Spring Cloud 对 Eureka 进行了集成,并作为优先推荐方案进行宣传,虽然目前 Eureka 2.0 已经停止维护,新的微服务架构设计中,也不再建议使用,但是目前依然有大量公司的微服务系统使用 Eureka 作为注册中心。

Eureka 主要分为两个部分:

  • Eureka Server:作为注册中心 Server 端,向微服务应用程序提供服务注册,发现,健康检查等能力。
  • Eureka Client:服务提供者,服务启动时,会向 Eureka Server 注册自己的信息 (IP,端口,服务信息等),Eureka Server 会存储这些信息。

关于 Eureka 的学习,主要包含以下三个部分:

  1. 搭建 Eureka Server
  2. 将 order-service, product-service 都注册到 Eureka
  3. order-service 远程调用时,从 Eureka 中获取 product-service 的服务列表,然后进行交互

三、搭建 Eureka Server

Eureka-server 是一个独立的微服务。

3.1 创建 Eureka-server 子模块

3.2、引入 eureka-server 依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

3.3 项目构建插件

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

3.4、完善启动类

给该项目编写一个启动类,并在启动类上添加 @EnableEurekaServer 注解,开启 eureka 注册中心服务。

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

3.5、编写配置文件

server:
  port: 10010
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: localhost
  client:
    fetch-registry: false # 表示是否从 EurekaServer 获取注册信息,默认为 true。因为这是一个单点的 EurekaServer,不需要同步其他的 EurekaServer 节点的数据,这里设置为 false
    register-with-eureka: false # 表示是否将自己注册到 EurekaServer,默认为 true。由于当前应用就是 EurekaServer,故而设置为 false.
  service-url:
    defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

启动服务后,注册中心就可以实现了。

四、服务注册

接下来我们把 product-service 注册到 eureka-server 中。

4.1、引入 eureka-client 依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

4.2、完善配置文件

添加服务名称和 eureka 地址。

spring:
  application:
    name: product-service
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10010/eureka

启动后服务注册成功。

五、服务发现

接下来我们修改 order-service,在远程调用时,从 eureka-server 拉取 product-service 的服务信息,实现服务发现。

5.1、引入依赖

服务注册和服务发现都封装在 eureka-client 依赖中,所以服务发现时,也是引入 eureka-client 依赖。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

5.2 完善配置文件

spring:
  application:
    name: order-service
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10010/eureka

5.3、远程调用

@Slf4j
@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    
    @Resource
    private DiscoveryClient discoveryClient;
    
    @Autowired
    private RestTemplate restTemplate;

    public OrderInfo selectOrderById(Integer orderId) {
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
        // String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();
        // 根据应用名称获取服务列表
        List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
        // 服务可能有多个,获取第一个
        EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(0);
        log.info(instance.getInstanceId());
        // 拼接 url
        String url = instance.getUri() + "/product/" + orderInfo.getProductId();
        ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}

六、Eureka 和 Zookeeper 区别

Eureka 和 Zookeeper 都是用于服务注册和发现的工具,区别如下:

  1. Eureka 是 Netflix 开源的项目,而 Zookeeper 是 Apache 开源的项目。
  2. Eureka 基于 AP 原则,保证高可用,Zookeeper 基于 CP 原则,保证数据一致性。
  3. Eureka 每个节点都是均等的,Zookeeper 的节点区分 Leader 和 Follower 或 Observer,也正因为这个原因,如果 Zookeeper 的 Leader 发生故障时,需要重新选举,选举过程集群会有短暂时间的不可用。

七、总结

本文介绍了 Spring Cloud 中 Eureka 的基本配置与使用流程,涵盖了服务注册中心的原理、CAP 理论分析以及具体的代码实现。

目录

  1. 一、背景
  2. 1.1、问题描述
  3. 1.2、解决思路
  4. 1.3、什么是注册中心?
  5. 1.4、CAP 理论
  6. 1.5、常见的注册中心
  7. 二、Eureka 介绍
  8. 三、搭建 Eureka Server
  9. 3.1 创建 Eureka-server 子模块
  10. 3.2、引入 eureka-server 依赖
  11. 3.3 项目构建插件
  12. 3.4、完善启动类
  13. 3.5、编写配置文件
  14. 四、服务注册
  15. 4.1、引入 eureka-client 依赖
  16. 4.2、完善配置文件
  17. 五、服务发现
  18. 5.1、引入依赖
  19. 5.2 完善配置文件
  20. 5.3、远程调用
  21. 六、Eureka 和 Zookeeper 区别
  22. 七、总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 数据结构核心:树与堆的概念及存储实现
  • MySQL 覆盖索引:原理、优势与适用场景
  • Stack-Chan 机器人开发与使用指南
  • Ghidra 开源逆向分析工具详解
  • OpenClaw AI Agent 实战指南:橙皮书与蓝皮书核心内容解析
  • 基于 AI 辅助的 Java 在线考试系统开发实践
  • Zotero 插件接入 DeepSeek AI 实现文献智能分析配置指南
  • Vivado 2023.2 安装教程:从零搭建 FPGA 开发环境
  • Llama.cpp 部署教程:老旧电脑运行大模型方案
  • KingbaseES 内核级 SQL 防火墙:白名单防护与零误报实践
  • Docker 拉取镜像超时解决方案:配置镜像加速器及隐藏设置
  • OpenClaw 飞书机器人配置指南:多渠道 AI 助手集成
  • 机器人调度系统交通管制与路径规划算法详解
  • 使用 OpenClaw 自动化发布 AI 新闻至微信与小红书
  • Faster-Whisper 本地实时语音识别部署与实战指南
  • 5 分钟切换不同 AI 引擎:Codex 多模型支持实战指南
  • YOLOv11 数据集训练、推理及网络结构详解
  • YOLO 算法进阶提升:骨干网络、特征融合与损失函数改进
  • 伺服驱动器 FPGA 架构实现:电流环 速度环 位置环及 SVPWM 设计
  • SHCTF 3rd Web 部分题目 Writeup

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online