为什么需要服务注册与发现?

在微服务架构中,服务实例的网络位置是动态变化的。想象一下电商系统中的购物车服务需要调用商品服务:

  • 商品服务部署了多个实例(192.168.1.10:8081、192.168.1.11:8082…)
  • 购物车服务该如何知道每个实例的地址?
  • 如果某个商品服务实例宕机了怎么办?
  • 新部署的商品服务实例如何被购物车服务发现?

服务注册与发现就是为了解决这些问题而生的!

注册中心工作原理

核心角色

  • 服务提供者:提供业务接口的服务(如商品服务)
  • 服务消费者:调用其他服务的服务(如购物车服务)
  • 注册中心:管理所有服务实例的注册信息

工作流程

1. 注册服务
2. 订阅服务
3. 返回实例列表
4. 负载均衡
5. 发起调用
服务提供者
注册中心
服务消费者
选择实例

具体流程

  1. 服务注册:服务启动时向注册中心注册自己的信息(服务名、IP、端口)
  2. 服务发现:消费者从注册中心获取服务实例列表
  3. 健康检查:提供者定期发送心跳,注册中心剔除异常实例
  4. 动态更新:实例变化时,注册中心通知消费者更新列表

Nacos 简介

Nacos(Naming and Configuration Service)是阿里巴巴开源的服务注册发现和配置管理平台,具有以下特点:

  • ✅ 服务注册与发现
  • ✅ 配置管理
  • ✅ 服务健康监测
  • ✅ 动态 DNS 服务
  • ✅ 中文文档完善

实战:基于 Nacos 的服务注册与发现

环境准备

1. 部署 Nacos

使用 Docker 快速部署:

docker run -d \
--name nacos \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim

访问:http://localhost:8848/nacos(账号/密码:nacos/nacos)

2. 服务注册示例

添加依赖
<!-- pom.xml -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置 Nacos
# application.yml
spring:
  application:
    name: item-service  # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848  # Nacos地址
启动服务
@SpringBootApplication
@EnableDiscoveryClient  // 启用服务发现
public class ItemServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ItemServiceApplication.class, args);
    }
}

启动后,在 Nacos 控制台可以看到注册的服务:
访问:http://localhost:8848/nacos(账号/密码:nacos/nacos)

在这里插入图片描述

3. 服务发现示例

服务消费者配置

同样添加依赖和配置:

spring:
  application:
    name: cart-service
  cloud:
    nacos:
      server-addr: localhost:8848
使用 DiscoveryClient 发现服务
@RestController
@RequestMapping("/cart")
public class CartController {
    
    @Autowired
    private DiscoveryClient discoveryClient;
    
    @Autowired
    private RestTemplate restTemplate;
    
    @GetMapping("/items/{id}")
    public Item getItem(@PathVariable Long id) {
        // 1. 获取商品服务实例列表
        List<ServiceInstance> instances = discoveryClient.getInstances("item-service");
        
        if (instances.isEmpty()) {
            throw new RuntimeException("没有可用的商品服务实例");
        }
        
        // 2. 负载均衡:随机选择一个实例
        ServiceInstance instance = instances.get(new Random().nextInt(instances.size()));
        
        // 3. 构造请求URL
        String url = String.format("http://%s:%s/items/%d", 
            instance.getHost(), instance.getPort(), id);
        
        // 4. 发起调用
        return restTemplate.getForObject(url, Item.class);
    }
}
使用 @LoadBalanced 简化调用

Spring Cloud 提供了更简洁的方式:

@Configuration
public class RestTemplateConfig {
    
    @Bean
    @LoadBalanced  // 开启负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

@RestController
@RequestMapping("/cart")
public class CartController {
    
    @Autowired
    private RestTemplate restTemplate;
    
    @GetMapping("/simple/{id}")
    public Item getItemSimple(@PathVariable Long id) {
        // 直接使用服务名调用,LoadBalancer会自动处理服务发现和负载均衡
        return restTemplate.getForObject(
            "http://item-service/items/" + id, Item.class);
    }
}

核心特性详解

1. 健康检查与故障转移

Nacos 通过心跳机制监控服务健康状态:

  • 服务实例每 5 秒向 Nacos 发送一次心跳
  • Nacos 15 秒未收到心跳会将实例标记为不健康
  • 30 秒未收到心跳会将实例从服务列表剔除,连接服务宕机情况

2. 负载均衡策略

Spring Cloud LoadBalancer 支持多种策略:

@Configuration
public class LoadBalancerConfig {
    
    @Bean
    public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
        Environment environment, LoadBalancerClientFactory factory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(
            factory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

3. 服务集群与权重配置

在 Nacos 中可以配置集群和实例权重:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        cluster-name: BEIJING  # 集群名称
        weight: 0.5  # 权重,范围 0-1

完整示例流程图

Cart Service Nacos Item Service 实例1 Item Service 实例2 注册服务 (item-service) 注册服务 (item-service) 服务启动时注册 订阅 item-service 服务 返回实例列表 [I1, I2] 心跳 心跳 loop [心跳检测] 负载均衡选择实例 调用商品查询接口 返回商品信息 实例2宕机 检测到I2心跳超时 通知实例列表更新 [I1] 后续请求只发往健康实例I1 Cart Service Nacos Item Service 实例1 Item Service 实例2

总结

Nacos 作为服务注册发现中心,解决了微服务架构中的关键问题:

  • 动态服务管理:自动处理服务实例的上线下线
  • 负载均衡:内置多种负载均衡策略
  • 健康监测:实时监控服务状态,自动剔除故障实例
  • 服务治理:支持集群、权重、元数据等高级特性

通过简单的配置和注解,我们就可以轻松实现服务的注册与发现,让微服务之间的调用更加灵活和可靠。


以上就是关于 Nacos 服务注册发现的详细介绍。在实际项目中,合理使用注册中心能够大幅提升微服务架构的稳定性和可维护性。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐