当前位置: 首页 > news >正文

分布式系统设计实战 - 服务注册中心最佳选型

1、概述

        前面我们学习了如何使用 SpringCloud 快速的构建一套分布式系统,通过代码案例的方式演示了 SpringBoot 、 Nacos、Gateway、Loadbalancer 以及 OpenFeign 等基本组件的使用,我们以及具备搭建一个基本的分布式系统的能力了,但是站在系统架构的层面上,我们还需要考虑很多的因素,比如注册中心的选型、服务网关选型、RPC重试机制、以及负载均衡等等。

        想了很久,我们就先对服务注册中心展开深入的讨论,如何根据自己的业务系统做出合适的技术选型,后续我们再逐步的进行其他的基础设施建 展开分析。

2、服务注册中心

2.1、注册中心简介

        在前面的文章  玩转 SpringCloud - 快速构建分布式系统详解  中已经介绍了 nacos  这款注册中心产品,相信你肯定知道服务注册中心是什么以及它的作用了。今天我们就来学习一下市面上主流的开源注册中心产品。主要包括 Zookeeper、Nacos、Consoul、etcd 以及过时的Eureak。

2.2、环境准备

        这里我们沿用上一篇文章的中的代码案例,相关代码我已经提交到 gitee了,如果想从头开始搭建可以参考前面的文章 

文章连接:
https://blog.csdn.net/qq_38701478/article/details/145702897?spm=1001.2014.3001.5501代码链接:
https://gitee.com/skr_coder/cloud-practice

软件版本信息如下:

JDK: 17
SpringBoot:  3.3.4
SpringCloud: 2023.0.3
SpringCloudAlibaba: 2023.0.3.2

2.3、Zookeeper 集成案例 

2.3.1、Zookeeper 环境搭建

        我们准备好 Zookeeper 的软件包,解压后来到 bin 目录 双击 zkServer.cmd  启动  Zookeeper 服务。

2.3.2、项目环境搭建

接着我们在原来的工程添加依赖信息,相关依赖信息如下

   <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

需要注意的是 gateway 和 Center 工程都需要添加

接着分别修改 用户服务和账户服务以及网关工程的 配置文件 ,相关内容如下:

server:port: 9000spring:application:name: account-service
#  cloud:
#    nacos:
#      server-addr: 127.0.0.1:8848cloud:zookeeper:connect-string: 127.0.0.1:2181 # Zookeeper 服务器地址,默认端口是 2181discovery:enabled: true # 启用服务发现功能

 最后分别检查启动类上是否添加了 开启服务发现的注解 @EnableDiscoveryClient 

2.3.3、服务测试

上述步骤完成后即可启动三个工程进行测试了。启动后如下所示

接着我们使用工具调用 创建账户接口来 创建一个账户 相关结果如下图所示

2.3.4、 查看服务信息

我么可以使用命令行工具登陆到Zookeeper 服务端 查看相应的服务信息,双击 zkCli.cmd 打开终端,输入 ls /services  命令就可以看到 服务列表了。

我们还可以使用get 命令获取具体服务信息 ,我们先来看网关工程的服务信息

具体内容如下,相信你肯定能看懂 ,这里说明下 由于我的 网关工程没有配置应用的名字 所以 name 使用了默认值 application 

{"name": "application","id": "245dada4-4057-428a-b71e-2aac9eeb36a9","address": "XY-YK-YX-WCAN","port": 80,"sslPort": null,"payload": {"@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance","id": "application","name": "application","metadata": {"instance_status": "UP"}},"registrationTimeUTC": 1747832116612,"serviceType": "DYNAMIC","uriSpec": {"parts": [{"value": "scheme","variable": true}, {"value": "://","variable": false}, {"value": "address","variable": true}, {"value": ":","variable": false}, {"value": "port","variable": true}]}
}

我们继续看用户服务 的信息

格式化后如下所示

{"name": "user-service","id": "bc92841d-670a-4dba-b23f-83f382950ac5","address": "XY-YK-YX-WCAN","port": 8001,"sslPort": null,"payload": {"@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance","id": "user-service","name": "user-service","metadata": {"instance_status": "UP"}},"registrationTimeUTC": 1747832120483,"serviceType": "DYNAMIC","uriSpec": {"parts": [{"value": "scheme","variable": true}, {"value": "://","variable": false}, {"value": "address","variable": true}, {"value": ":","variable": false}, {"value": "port","variable": true}]}
}

2.4、Consul 集成案例

2.4.1、Consul 环境准备

首先下载安装包,下载地址如下

https://developer.hashicxiazaorp.com/consul/install#windows

 接着我们解压下载的软件包,cmd 进入 解压目录

参照官方文档,我们可以使用 consul agent -dev 命令启动 服务

https://developer.hashicorp.com/consul/commands

服务启动后浏览器访问  http://localhost:8500  即可进入控制台

2.4.2、项目环境准备

依赖信息如下:

 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency>

配置信息如下:

#------  consulcloud:consul:host: 127.0.0.1  # Consul 服务地址port: 8500  # Consul 默认端口discovery:enabled: true  # 启用服务发现discovery:enabled: true  # 启用服务注册与发现

 需要将之前的 zookeeper 和 nacos 的配置注释 或者删除

2.3.4、查看服务信息

 和前面一样我们启动几个服务即可,这里我的网关工程报错了,报错信息如下:

Caused by: java.lang.IllegalArgumentException: 
Consul service ids must not be empty, must start with a letter, 
end with a letter or digit, and have as interior characters only letters, digits, and hyphen: 80

报错原因就是 没有设置 application name ,我们在 application.yml 中添加配置即可

spring:application:name: gateway

项目启动后,进入管理控制台查看服务信息

好家伙,我们发现服务前面都有个红叉,一看就知道 这是不好的现象。我们点进去发现报错信息如下

HTTP GET http://XY-YK-YX-WCAN:9001/actuator/health: 404  Output: 
<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>
Wed May 21 22:26:17 CST 2025</div><div>There was an unexpected error(type=Not Found, status=404).</div></body></html>

意思就是没有找到健康检查的端点,好吧 这里我们需要在 网关工程 和 Center 中 加入 actuator 依赖 

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>

重启服务发现都正常了。

2.3.4、服务测试

 我们打开工具测试,发现服务调用也是正常的

 2.5、Eureka 介绍

        曾经 Eureka 也是一种比较热门的注册中心产品,也是 第一代 SpringCloud 体系中默认的注册中心,它不需要安装单独的软件包,直接以jar包的形式与业务系统集成,可以方便、快速的实现服务注册、注销、健康检查等功能。

        但是后来开源的版本停止维护了,所以大家就寻找了其他的替代方案,这里就不再提供集成的案例代码了。

2.6、Nacos 集成案例

2.6.1、Nacos 环境准备

        首先我们到官方网站下载软件包 链接

https://nacos.io/?spm=5238cd80.3a4808a9.0.0.1b44411drCbw9x

我们选择下载 2.4.3 的版本,

下载完成后解压压缩包,进入bin 目录 使用 startup.cmd -m standalone  命令启动

 浏览器访问  http://192.168.241.1:8848/nacos/index.html 

 2.6.2、项目环境准备

步骤和前面的类似,网关工程和 Center 添加 nacos 依赖,用户服务、账户服务 和 网关 修改配置文件,这里不再赘述了。

依赖信息如下 : 

 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

配置信息如下:

#------  nacoscloud:nacos:server-addr: 127.0.0.1:8848

 修改完成后启动服务就可以在控制台看到具体的服务信息了。

2.6.3、服务测试

和前面一样的测试即可,这里不再赘述了。

2.7、Etcd 集成案例

2.7.1、Etcd 环境准备

        首先下载安装包,我们这里去 github 下载。本文以 Linux 环境为例,(害。。。。Windows 下操作好几遍失败了)

https://github.com/etcd-io/etcd/releases

我么登陆到终端上,尽量使用 root 用户 或者具备 root 权限的用户 

首先安装 wget 和 systemd 

yum install -y wget systemd

接着创建一个 shell 脚本,脚本内容如下

# 新建一个 shell 文件vim etcd_install.sh## shell 文件中的内容ETCD_VERSION=v3.5.0
wget https://github.com/etcd-io/etcd/releases/download/${ETCD_VERSION}/etcd-${ETCD_VERSION}-linux-amd64.tar.gz
tar xzvf etcd-${ETCD_VERSION}-linux-amd64.tar.gz
sudo mv etcd-${ETCD_VERSION}-linux-amd64/etcd /usr/local/bin/
sudo mv etcd-${ETCD_VERSION}-linux-amd64/etcdctl /usr/local/bin/

 保存后给 etcd_install.sh  赋权  

chmod 755 etcd_install.sh

然后运行脚本,等待执行完成即可 

查看安装版本信息

 安装完成后我们需要做相关的配置。

新建一个 etcd.env 文件,用于设置 Etcd 的启动参数 。

# 新建文件
vim /etc/etcd.env# 添加以下内容
# 单节点配置示例
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.200.19:2379"

其中 ETCD_LISTEN_CLIENT_URLS 表示 指定 etcd 节点监听客户端连接的地址和端口,这里我们设置的 0.0.0.0 表示监听所有网络,也就是说局域网内的任意ip都能注册进来。ETCD_ADVERTISE_CLIENT_URLS 用来指定微服务访问的ip 和端口

接着 创建一个 Systemd 服务文件,用来管理 etcd 服务 ,相关命令如下

# 新建文件
vim /etc/systemd/system/etcd.service# 加入以下内容 [Unit]
Description=Etcd Server
After=network.target[Service]
Type=simple
EnvironmentFile=-/etc/etcd.env
ExecStart=/usr/local/bin/etcd
Restart=on-failure[Install]
WantedBy=multi-user.target

最后我们可以启动服务了


# 启动服务
sudo systemctl start etcd
# 查看状态
sudo systemctl enable etcd

2.7.2、项目环境准备

依赖信息

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-etcd</artifactId>
</dependency>

 添加依赖

cloud:etcd:endpoints: http://192.168.200.98:2379  # Etcd 服务的地址acl: false  # 是否启用访问控制列表(根据需要设置)enabled: true  # 启用 Etcd 注册中心ttl: 30  # 服务注册的超时时间(可选)

最后启动项目即可进行测试。 

3、CAP 理论

3.1、理论概述

        前面介绍了主流的几种注册中心的集成方式 和基本的使用,这个章节里我们来聊聊 CAP 理论。CAP 理论是由计算机科学家 Eric Brewer 在 2000 年的 ACM Symposium 上提出的。旨在描述分布式计算系统中一致性、可用性和分区容忍性之间的权衡关系。

        他指出在分布式系统中,无法同时满足一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)这三个要素,最多只能满足其中两个。

通常情况下,我们认为网络分区是必然存在的,因此大多数时候 P 是必选的,我们都是在 C 和 A 之间做取舍。 也就是 CP 和 AP 。

3.2、CP 系统

        所谓的CP 系统 就是 牺牲可用性,保证强一致性和分区容忍性。他的典型场景有: 银行转账、库存扣减等对数据准确性要求极高的场景。

        代表性的技术是  Zookeeper、Etcd、Consul(CP 模式)。当发生网络分区时,系统可能拒绝请求(如返回超时错误),直到分区恢复

3.3、AP 系统

牺牲一致性 保证高可用性和分区容忍性,但数据可能短暂不一致。

典型场景:社交媒体、电商商品详情页等容忍短暂数据延迟的场景。

代表技术:Eureka、Cassandra、Nacos(AP 模式)。

代价:用户可能读到旧数据(最终一致性)。

3.4、CA 系统

        不支持网络分区,想想有哪些场景下是不存在网络分区的问题或者说是 网络是绝对可靠的 ,大概只有单机环境吧 ,很显然分布式系统中必然存在网络分区的问题。

4、BASE 理论

4.1、相关概念

下面先看看 BASE 是什么

  • BA(Basically Available)基本可用:系统在故障时仍能提供核心功能(如降级、限流)。

  • S(Soft State)软状态:允许系统中的数据存在中间状态(不同节点的数据可能暂时不一致)。

  • E(Eventual Consistency)最终一致性:经过一段时间后,所有节点的数据会达成一致。

你的注意力应该放在 E 上,也就是最终一致性。我们可以认为 BASE 是对 CAP 中 AP 架构的补充,强调通过牺牲强一致性来换取高可用性,适用于对延迟敏感但允许最终一致性的场景。

4.2、应用场景

        我们在更新缓存的时候,缓存节点间数据可能短暂不一致,但最终通过异步同步达成一致。这就是 最终一致性。

4.3、CAP 和 BASE 

特性CAPBASE
核心目标强一致性 vs 高可用性高可用性 + 最终一致性
一致性模型强一致性(CP)或弱一致性(AP)最终一致性
适用场景金融交易、配置管理社交网络、实时性要求低的业务
典型技术Zookeeper、EtcdCassandra、DynamoDB、Nacos

5、主流注册中心比对

5.1、 Zookeeper(CP 型)

  • 特点

    • 基于 ZAB 协议,强一致性(CP),牺牲可用性。

    • 通过临时节点(Ephemeral Nodes)实现服务注册与心跳检测。

    • 适用场景:数据一致性要求高的场景(如分布式锁、配置管理)。

  • 缺点

    • 选举期间(30-120秒)服务不可用,不适合高可用性要求的服务发现。

    • 客户端需自行处理服务列表的监听与刷新,复杂度较高。

5.2、Eureka(AP 型)

  • 特点

    • 去中心化架构(Peer-to-Peer),强调高可用性(AP)。

    • 支持自我保护机制(网络分区时保留旧数据),适合云环境。

    • 与 Spring Cloud 集成度高,适合快速开发。

  • 缺点

    • 数据最终一致性,可能出现短暂不一致。

    • 默认配置下服务发现延迟较高(分钟级),需手动优化参数5。

5.3、Consul(CP 型)

  • 特点

    • 基于 Raft 协议,强一致性(CP),支持多数据中心。

    • 一站式服务(服务发现、健康检查、KV 存储、DNS 支持)。

    • 适合需要跨区域部署和强一致性的场景。

  • 缺点

    • 注册时间较长(需半数节点确认)。

    • 对 Go 语言依赖较强,侵入性较高。

5.4、Nacos(AP/CP 可选)

  • 特点

    • 支持 AP 和 CP 模式切换,灵活性高。

    • 集成服务发现与动态配置管理,适合微服务全生命周期管理。

    • 对 Spring Cloud 和 Dubbo 生态兼容性好,适合混合云场景。

  • 缺点

    • 社区生态相对年轻,大规模生产验证案例较少。

5.5、ETCD(CP 型)

  • 特点

    • 基于 Raft 协议,强一致性,性能高(每秒千级写操作)。

    • 与 Kubernetes 深度集成,是云原生场景的默认选择。

    • 支持 SSL 认证,安全性强。

  • 缺点

    • 功能单一(主要面向键值存储),需额外组件支持服务发现。

6、 选型建议

6.1、何时选择 CP 系统

  • 强一致性需求:如支付系统、分布式锁、配置中心。

  • 技术栈依赖:Kubernetes(依赖 Etcd)、Dubbo(依赖 Zookeeper)。

6.2、 何时选择 AP + BASE

  • 高并发高可用场景:如电商大促、社交网络热点事件。

  • 容忍数据延迟:如商品评论、用户行为日志。

6.3、 混合架构实践

  • 分级一致性:核心交易链路用 CP(如订单支付),非核心链路用 AP(如用户积分)。

  • Nacos 的双模式:根据服务类型切换 AP/CP 模式(如配置中心用 CP,服务发现用 AP)。

6.4、多维度选型

6.4.1、 根据 CAP 需求选择

  • 强一致性(CP)场景

    • Zookeeper:适合传统分布式系统(如 Hadoop、Dubbo)的协调服务。

    • Consul:需多数据中心支持或一站式解决方案时优先考虑。

    • ETCD:Kubernetes 生态首选,云原生场景必选。

  • 高可用性(AP)场景

    • Eureka:Spring Cloud 技术栈的简单选择,适合中小规模。

    • Nacos:需要动态配置管理或混合部署时优选。

6.4.2、 根据技术栈选择

  • Spring Cloud:优先 Nacos 或 Eureka(历史项目)。

  • Dubbo:推荐 Zookeeper 或 Nacos

  • KubernetesETCD 是默认选择,Consul 可作补充。

6.4.3、根据功能需求选择

  • 动态配置管理Nacos(内置配置中心)或 Consul(需结合 Vault)。

  • 多数据中心Consul 或 Nacos(需手动配置)。

  • 轻量级与易用性Nacos(界面友好) > Eureka > Consul

6.4.4、性能与规模

  • 大规模服务实例(万级节点):Nacos(水平扩展能力强)或 ETCD(高性能)。

  • 中小规模Eureka(简单)或 Consul(功能全面)。

7、总结

        我们透彻的将 CAP 理论其实是设计上的一种理论,它主要帮助我们理解分布式系统的本质矛盾,明确架构的取舍方向。而BASE 理论则是一种实践指导,在 AP 架构下,通过最终一致性平衡业务需求与技术复杂度。有了这些基础知识的支撑 我们就可以根据自己的业务系统做出合适的 技术选型了。

http://www.xdnf.cn/news/626275.html

相关文章:

  • char类型既能表达字符又能表达整数
  • IDEA中创建SpringBoot项目没有Java8
  • 初级消防设施操作员证有用吗?
  • 香橙派3B学习笔记2:Vscode远程SSH登录香橙派_权限问题连接失败解决
  • Neural ODE(神经常微分方程网络)深度解析
  • C# 高性能写入txt大量数据
  • Java IO流学习指南:从小白到入门
  • PS2025 v26.7 Photoshop2025+AI生图扩充版,支持AI画图
  • 【Redis】1-高效的数据结构P3-压缩列表与对象
  • 函数式编程思想详解
  • MATLAB 2023b 配电柜温度报警系统仿真
  • 41-牧场管理系统
  • 【RAG文档切割】从基础拆分到语义分块实战指南
  • 在STM32上配置图像处理库
  • Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用
  • Spring AI 使用教程
  • Non-blocking File Ninja: 异步文件忍者
  • 人形机器人通过观看视频学习人类动作的技术可行性与前景展望
  • 《AVL树完全解析:平衡之道与C++实现》
  • 如何保证 Kafka 数据实时同步到 Elasticsearch?
  • NHANES指标推荐:PHDI
  • RT Thread Nano V4.1.1 rtconfig.h 注释 Configuration Wizard 格式
  • 【TCP/IP协议族详解】
  • Docker安装MySQL集群(主从复制)
  • 关于gt的gt_data_valid_in信号
  • LeetCode-贪心-买卖股票的最佳时机
  • 【算法】力扣体系分类
  • QML学习05MouseArea
  • 51、c# 请列举出6个集合类及用途
  • VLLM推理可以分配不同显存限制给两张卡吗?