SpringCloud——注册中心Service Registry —— [服务治理]

注册中心

是微服务架构中的一个核心基础组件,它扮演着服务目录的角色。它的核心功能是实现服务发现(Service Discovery)

核心职责:

服务注册(Service Registration): 微服务实例在启动时,主动将自己的网络位置信息(如 IP 地址、端口号)、
服务名称、健康状态、元数据(Metadata,如版本、环境标签)等发送并存储到注册中心

服务维护(Service Maintenance): 服务实例会定期向注册中心发送心跳(Heartbeat) 信号以表明自己仍然存活。
如果注册中心在预定义的超时时间内没有收到某个实例的心跳,则认为该实例已下线或不可用,并将其从服务目录中移除(服务注销)

服务查询(Service Lookup): 当服务消费者(Client)需要调用某个服务提供者(Provider)时,
它会向注册中心查询该服务名称下所有可用且健康的实例列表

为什么需要注册中心?

在微服务架构中,服务数量众多,实例动态变化(扩缩容、故障、滚动更新),服务间的调用关系复杂。注册中心解决了在这种动态环境下服务消费者如何找到服务提供者这个根本问题。没有它,微服务将难以有效运作。

注册中心会带来哪些问题? (挑战与复杂性)

  • 单点故障风险:

    问题: 如果注册中心本身完全宕机,服务实例无法注册/续约,消费者也无法查询服务实例列表,
    可能导致整个微服务系统瘫痪。
    
    应对: 注册中心必须以集群(Cluster) 方式高可用部署(至少 3 个或更多节点)。
    采用共识算法(如 Raft)保证集群内数据一致性。即使部分节点宕机,整个注册中心仍能对外提供服务。
    
  • 数据一致性问题:

     问题: 在注册中心集群中,如何保证所有节点上存储的服务实例信息是强一致的?这涉及到分布式系统著名的 CAP 定理。
    
     权衡: 不同的注册中心实现有不同的侧重:
     
     CP 型 (Consistency & Partition Tolerance): 如 ZooKeeper, etcd。在网络分区(脑裂)发生时,
     优先保证数据一致性,可能	导致部分节点暂时不可注册或查询(牺牲可用性 A)。适合对一致性要求极高的场景。
     
     AP 型 (Availability & Partition Tolerance): 如 Eureka, Nacos (默认 AP 模式)。在网络分区时优先保证可用性,
     节点仍能接受注册和查询,但不同节点间的数据可能暂时不一致(最终一致)。适合需要高可用性的微服务场景,也是主流选择。
     最终一致性: AP 型注册中心通常保证最终一致性,即故障恢复后,数据会通过同步机制达到一致状态。
    

Java 微服务架构的服务治理中,通常涉及三个核心角色,它们协同工作以实现服务的注册、发现、调用和管理:

1.服务注册中心 (Service Registry / Discovery Server)
职责: 这是服务治理的核心基础设施。它充当一个动态的目录服务。

功能:
服务注册: 接收服务提供者实例启动时发送的注册请求,记录其网络位置(IP、端口)、服务名、元数据(版本、健康状态、权重等)。
服务注销: 接收服务提供者实例关闭或心跳超时时发送的注销请求,将其从目录中移除。
服务发现: 响应服务消费者的查询请求,返回符合条件(通常是服务名)的、当前可用的服务提供者实例列表(及其元数据)。
健康检查: 定期检查或被动接收服务实例的心跳,标记不健康的实例,确保发现列表的可用性。

2.服务提供者 (Service Provider)
职责: 提供具体业务功能或数据的微服务实例。

功能:
启动注册: 在应用启动时,主动向服务注册中心注册自己,告知其服务名和网络位置等信息。
发送心跳: 在运行期间,定期向注册中心发送心跳包,证明自己仍然存活且健康。如果停止发送心跳(如进程崩溃),注册中心会将其标记为不健康或移除。
提供服务: 监听特定端口,接收并处理来自服务消费者的远程调用请求。
优雅下线: 在应用关闭前,主动向注册中心发送注销请求,避免消费者调用到正在关闭的实例。

3.服务消费者 (Service Consumer / Client)
职责: 需要调用其他微服务来完成自身功能的微服务实例(实际上,一个服务通常既是提供者也是消费者)。

功能:
服务发现: 在需要调用某个服务时,向服务注册中心查询目标服务名对应的、当前可用的提供者实例列表。
负载均衡: 从注册中心获取到多个实例列表后,根据内置或配置的负载均衡策略(如轮询、随机、响应时间加权等)选择一个具体的实例进行调用。
发起调用: 使用网络客户端(如Ribbon + RestTemplate, OpenFeign, Dubbo Client, gRPC Stub等)向选定的服务提供者实例发起实际的远程调用(REST, RPC等)。
容错处理: 处理调用过程中可能发生的超时、错误、熔断等异常情况(通常结合Hystrix, Resilience4j, Sentinel等组件实现)。
缓存服务信息: 通常会缓存从注册中心获取的服务实例信息,避免每次调用都查询注册中心,提高效率并降低注册中心压力(缓存会定期刷新或根据注册中心通知更新)。

三者协同工作流程:

提供者启动: 服务提供者启动 -> 向服务注册中心注册自己。

消费者需要调用: 服务消费者需要调用服务X -> 向服务注册中心查询服务X的可用实例列表。

注册中心响应: 服务注册中心返回服务X的健康实例列表给服务消费者。

消费者选择并调用: 服务消费者使用负载均衡策略从列表中选择一个实例 -> 直接向该服务提供者实例发起网络调用。

提供者响应: 服务提供者处理请求并返回响应给服务消费者。

持续健康检查: 服务注册中心持续接收服务提供者的心跳,更新健康状态。不健康的实例会被剔除,不再返回给新的查询。

提供者下线: 服务提供者关闭前 -> 主动向服务注册中心注销 -> 服务注册中心移除该实例 -> 后续查询不再包含该实例。

——————————————————注册中心组件———————————————————————————

推荐组件:Alibaba Nacos

特点: 非常活跃的国产开源项目。一个平台解决两大核心问题:服务注册发现(Naming Service) 和 动态配置管理(Configuration Service)。支持 AP 和 CP 两种模式切换(默认 AP,满足大多数场景;需要强一致时切 CP)。功能丰富强大。
优点:
双中心合一: 注册中心和配置中心统一管理,降低运维复杂度。
模式可选: AP/CP 适应不同场景。
功能丰富: 支持健康检查(TCP/HTTP/MySQL 等)、权重管理、元数据管理、集群管理、命名空间(多租户隔离)、分组管理、配置管理、DNS-F、监听查询等。
生态友好: 完美支持 Spring Cloud、Spring Boot、Dubbo、Kubernetes Service。提供友好易用的管理控制台。
性能优异: 能支撑大规模服务注册。
缺点: 相对 Eureka 配置项稍多,概念也略多(需要理解命名空间、分组等)部署略复杂一点(但容器化后也很方便)

在这里插入图片描述

Nacos 服务注册

  1. 引入nacos discovery依赖
<!-- Nacos 服务注册与发现 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. yml配置Nacos地址
spring:
  application:
    name: item-service  # 此服务名称
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848  # Nacos 服务器地址和端口

Nacos 服务发现
消费者需要连接nacos以拉取和订阅服务,因此服务发现的前两步与服务注册是一样,后面再加上服务调用即可:

  1. 引入nacos discovery依赖
<!-- Nacos 服务注册与发现 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. yml配置Nacos地址
spring:
  application:
    name: item-service  # 此服务名称
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848  # Nacos 服务器地址和端口
  1. 服务发现
// 注入 [发现客户端] bean
private final DiscoveryClient discoveryClient;

private void handleCartItems(List<CartVO> vos) {
    // 1. 根据服务名称,拉取服务的实例列表
    List<ServiceInstance> instances = discoveryClient.getInstances("item-service");

    // 2. 负载均衡,挑选一个实例
    ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));

    // 3. 获取实例的 IP 和端口
    URI uri = instance.getUri();

    // ... 其他逻辑略
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值