SpringCloud 入门 - Nacos 服务治理

一、Nacos 核心认知与架构

1.1 什么是 Nacos

📌 核心定义:Nacos(Dynamic Naming and Configuration Service)是阿里巴巴开源的动态服务发现、配置管理与服务治理平台,核心目标是解决微服务架构中「服务注册发现」「配置集中管理」「服务可用性保障」三大核心痛点。其名称由 Naming(命名服务,负责服务定位)和 Configuration(配置服务,负责配置同步)组合而来,是 Spring Cloud Alibaba 生态中服务治理的「核心枢纽」。

🔍 深入理解:Nacos 并非单一功能组件,而是融合了「注册中心」「配置中心」「服务管理平台」的一体化解决方案,可替代 Eureka(注册中心)+ Spring Cloud Config(配置中心)+ Consul(服务治理)的组合,减少微服务架构的组件依赖复杂度。

1.2 Nacos 核心架构

📌 架构分层:Nacos 采用「分层设计」,从下到上分为四层,每层职责清晰:

  1. 基础设施层:提供日志、存储、通信等基础能力,支持 MySQL(数据持久化)、Raft(一致性协议)等;
  2. 核心服务层:包含「Naming Service(服务发现)」和「Config Service(配置管理)」两大核心模块,是 Nacos 的功能核心;
  3. API 层:对外提供 RESTful API、gRPC API 等接口,供客户端(微服务应用)调用;
  4. 接入层:提供控制台 UI、SDK(Java/Go 等)、Spring Cloud 集成适配,降低用户使用门槛。

💡 实用认知:生产环境中,Nacos 通常以「集群模式」部署,通过 Raft 协议保证数据一致性,避免单点故障;开发环境可使用「单节点模式」快速搭建。

1.3 Nacos 核心功能与价值

1.3.1 三大核心功能
功能模块核心能力解决的痛点
服务发现与注册支持 DNS/RPC 发现模式,服务自动注册、健康检查、实例动态感知微服务间调用需硬编码 IP: 端口,服务下线后调用失败;手动维护服务列表效率低
动态配置管理集中存储配置、支持灰度发布、配置实时更新(无需重启服务)配置分散在各服务节点,更新配置需重启服务;不同环境(dev/test/prod)配置混乱
服务治理提供集群管理、权重调整、负载均衡、命名空间隔离等能力服务单点故障风险高;跨地域调用延迟高;多环境服务相互干扰
1.3.2 核心优势

相比传统服务治理组件(如 Eureka、Consul),Nacos 具备以下不可替代的优势:

  • 开箱即用:单节点部署仅需下载压缩包、修改端口即可启动,无需复杂配置;
  • 双模式支持:可灵活切换「AP 模式」(可用性优先,适合服务发现,类似 Eureka)和「CP 模式」(一致性优先,适合配置管理,类似 Zookeeper);
  • 生态无缝集成:与 Spring Cloud、Spring Boot 深度适配,通过注解 / 配置即可快速集成,无需自定义开发;
  • 可视化能力强:提供功能丰富的控制台,支持服务实例查看、配置编辑、集群监控等,降低运维成本;
  • 迁移友好:支持从 Eureka、Zookeeper 等注册中心平滑迁移,提供数据导入工具和兼容 API。

1.4 Nacos 与主流服务治理组件对比

📌 特性对比:通过核心特性对比,可快速判断 Nacos 的适配场景:

特性NacosEurekaConsul
服务发现机制DNS/RPC 双支持RPC 支持DNS/RPC 双支持
配置管理原生支持(动态更新)不支持支持(需额外配置)
一致性协议AP/CP 可切换AP(最终一致性)CP(Raft 协议)
健康检查方式心跳 + 主动探测 + HTTP客户端心跳HTTP/TCP/gRPC
多环境隔离命名空间(原生)需自定义 metadata分区(Partition)
控制台功能丰富(服务 / 配置 / 监控)简单(仅服务列表)较丰富
生产环境部署复杂度中(集群需 3 + 节点)高(需配合 Eureka Server 集群)中(需配合 Consul Agent)

1.5 AP/CP 模式切换原理

🔍 核心差异:Nacos 支持 AP/CP 模式切换,本质是「一致性与可用性的权衡」,需根据业务场景选择:

  • AP 模式(Availability 优先)

    • 适用场景:服务发现(如微服务间调用),优先保证服务可用,允许短暂的数据不一致;
    • 原理:基于「最终一致性」,服务注册时无需等待所有 Nacos 节点同步完成,立即返回成功;节点故障时,剩余节点仍可提供服务;
    • 开启方式:默认模式(无需配置),或通过 API 设置 serviceMetadata 为 {"preserveInstanceId":true}
  • CP 模式(Consistency 优先)

    • 适用场景:配置管理(如数据库连接池参数)、有状态服务(如 Redis 集群),需保证数据强一致性;
    • 原理:基于 Raft 协议,服务注册 / 配置更新需等待集群中多数节点(N/2+1)同步完成后才返回成功,确保数据一致性;
    • 开启方式:通过控制台或 API 将服务设置为「持久化服务」(ephemeral: false),自动切换为 CP 模式。

⚠️ 注意事项:同一服务不能同时处于 AP 和 CP 模式;临时实例(ephemeral: true)仅支持 AP 模式,非临时实例(ephemeral: false)仅支持 CP 模式。

二、Nacos 服务注册与发现实战(含 API 详解)

2.1 前置准备:Nacos Server 部署

参考SpringCloud 入门 - 准备工作-优快云博客

2.2 服务注册核心流程与配置

2.2.1 核心依赖引入

📝 pom.xml 配置

    <!-- Nacos 服务发现核心依赖:自动注入服务注册/发现相关 Bean -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

</dependencies>
2.2.2 服务注册配置(application.yml)

📝 核心配置(以「user-service」为例):

server:
 port: 8091
spring:
 application:
   name: user-service

 #配置nacos
 cloud:
   nacos:
     discovery:
       server-addr: 192.168.222.128:8848
       cluster-name: JQ-SH
       # 以下为可选项
       # namespace: public # 命名空间 ID(默认 public,多环境隔离需自定义,如 dev/test)
       # weight: 1 # 服务权重(0~1,权重越高,接收请求比例越高)
       # ephemeral: true # 是否为临时实例(true=临时实例,AP 模式;false=非临时实例,CP 模式)
       # metadata: # 自定义元数据(如服务版本、环境标签,可用于服务筛选)
       #   version: v1
       #   env: dev

🔍 深入理解配置项

  • spring.application.name:服务的「逻辑名称」,Nacos 基于该名称聚合同一服务的所有实例;
  • ephemeral:实例类型开关,临时实例故障后会被 Nacos 自动剔除,非临时实例需手动注销;
  • metadata:自定义元数据,可在服务发现时筛选实例(如只调用 version: v1 的实例)。
2.2.3 启用服务注册(启动类)

📝 启动类代码

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/** * user-service 启动类 * @EnableDiscoveryClient:启用服务注册与发现(Spring Cloud 2020.0.0+ 版本可省略,自动生效) */
@SpringBootApplication
@EnableDiscoveryClient // ⚠️ 低版本(如 Spring Cloud Hoxton)需显式添加,高版本可省略
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

🔍 核心原理:服务启动时,NacosDiscoveryAutoConfiguration 自动加载,初始化 NacosServiceRegistry(服务注册器),调用 register() 方法将「服务名、实例 IP、端口、元数据」等信息注册到 Nacos Server,流程如下:

  1. 服务启动 → 加载 NacosDiscoveryAutoConfiguration
  2. 初始化 NacosServiceRegistry 和 NacosDiscoveryProperties(读取配置);
  3. NacosServiceRegistry 调用 register(Registration registration) 向 Nacos Server 发送注册请求;
  4. Nacos Server 接收请求,更新「服务注册表」,并同步到集群其他节点(若为集群模式);
  5. 注册成功后,服务定期发送心跳(默认 5 秒),维持实例健康状态。
2.2.4 服务注册验证

📝 验证步骤

  1. 启动 user-service 应用;
  2. 访问 Nacos 控制台 → 「服务管理」→ 「服务列表」;
  3. 找到 user-service,点击「详情」,查看实例信息(IP、端口、权重、元数据等);
  4. 若实例状态为「健康」,则服务注册成功。

⚠️ 常见问题排查

  • 服务注册不上?检查 server-addr 是否正确(IP: 端口是否可达)、spring.application.name 是否配置;
  • 实例状态为「不健康」?检查服务是否正常发送心跳(临时实例需确保网络通畅,非临时实例需检查 Nacos 主动探测配置)。

2.3 服务发现核心 API 与使用

2.3.1 服务发现实战(代码示例)

📝 获取服务实例并调用(以「order-service」调用「user-service」为例):

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

    // 注册 RestTemplate,@LoadBalanced 使其支持服务名调用和负载均衡
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @PostMapping("/create")
    public String createOrder() {
        // 1. 调用 user-service 的 /user/getUser 接口(用服务名替代 IP:端口)
        String userId = "123";  // 模拟用户ID
        // 服务名调用格式:http://服务名/接口路径
        String userUrl = "http://user-service/user/getUser/" + userId;
        String userInfo = restTemplate.getForObject(userUrl, String.class);

        // 2. 模拟创建订单逻辑
        String orderInfo = "订单创建成功,用户信息:" + userInfo;

        return orderInfo;
    }
}

💡 最佳实践:生产环境推荐使用「(服务名调用)」,无需手动管理实例 IP / 端口,且自动集成负载均衡;@LoadBalanced 底层通过「负载均衡拦截器」实现服务名到 IP: 端口的解析。

三、Nacos 服务治理高级特性(原理 + 实战)

3.1 多实例部署:解决服务单点故障

📌 核心概念:多实例指「同一服务(相同 spring.application.name)部署多个节点」,通过负载均衡分发请求,避免单个实例故障导致服务不可用,是服务高可用的「基础保障」。

3.1.1 多实例部署实战(IDEA 为例)

📝 部署步骤

  1. 打开 IDEA 「Run/Debug Configurations」→ 选中 user-service 启动配置;
  2. 按 Ctrl+D 复制配置,修改配置名称(如 user-service-8091);
  3. 点击「Modify options」→ 「Add VM options」,添加端口参数:-Dserver.port=8097(与原实例端口 8091 不同);
  4. 重复步骤 2-3,创建 user-service-8098(端口 8098);
  5. 依次启动 3 个实例,访问 Nacos 控制台 → 「user-service」详情,确认「实例数 = 3」。

⚠️ 关键注意:所有实例的 spring.application.name 必须完全一致,否则 Nacos 会视为不同服务;实例端口必须不同(同一机器上),避免端口冲突。

🔍 原理:Nacos 为每个实例生成唯一的「实例 ID」(格式:IP:端口#服务名#集群名),通过实例 ID 区分同一服务的不同节点;服务消费者拉取实例列表时,Nacos 会返回所有健康实例,供负载均衡组件选择。

3.2 集群管理:优化跨地域调用延迟

📌 核心概念:集群是「同一服务的实例按地域 / 机房划分的集合」(如上海集群 JQ-SH、深圳集群 JQ-BJ),通过「集群优先策略」实现「优先调用同地域实例」,减少跨地域网络延迟,同时实现「跨集群容错」(同集群无实例时调用其他集群)。

3.2.1 集群配置实战
步骤 1:服务提供者配置集群(user-service)

📝 application.yml 配置

spring:
  cloud:
    nacos:
      discovery:
        cluster-name: JQ-SH 
步骤 2:服务消费者配置集群优先策略(order-service)

📝 application.yml 配置

spring:
  cloud:
    loadbalancer:
      nacos:
        enabled: true # 📌 启用 Nacos 负载均衡扩展(必须开启,否则不生效)
# 针对 user-service 配置集群优先规则
user-service:
  ribbon:
    # 集群优先策略类:com.alibaba.cloud.nacos.ribbon.NacosRule
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
3.2.2 NacosRule 策略原理

🔍 执行流程

  1. 服务消费者(order-service)获取自身集群(如 SH);
  2. 从 Nacos 拉取 user-service 的实例列表,筛选出集群为 SH 的实例;
  3. 若同集群实例存在且健康,按「权重」分配请求(加权轮询);
  4. 若同集群无健康实例,自动切换到其他集群(如 BJ),避免服务不可用。

💡 实战场景:某电商平台在上海、北京部署 user-service,上海的 order-service 优先调用上海的 user-service,减少跨地域网络延迟(从 50ms 降至 10ms 以内);若上海集群故障,自动切换到北京集群,保障服务可用性。

3.3 负载均衡规则:按需选择请求分发策略

📌 核心定义:负载均衡规则是「服务消费者选择实例的算法」,Nacos 支持多种规则,适配不同业务场景,可通过配置指定。

3.3.1 常用负载均衡规则对比
规则类名核心逻辑适用场景
com.alibaba.cloud.nacos.ribbon.NacosRule集群优先 + 同集群加权轮询多集群部署,需优化跨地域延迟
com.netflix.loadbalancer.RoundRobinRule轮询(按实例顺序依次分配请求)单集群、所有实例性能相近
com.netflix.loadbalancer.RandomRule随机(随机选择实例)需均匀分配请求,无性能差异的场景
com.netflix.loadbalancer.WeightedResponseTimeRule响应时间加权(响应越快,权重越高)实例性能差异较大(如部分实例配置高)
com.netflix.loadbalancer.RetryRule重试策略(请求失败后,重试其他实例)高可用要求高,需减少请求失败率的场景
3.3.2 规则配置实战

📝 配置 WeightedResponseTimeRule(响应时间加权)

yaml

# 针对 user-service 配置负载均衡规则
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

🔍 原理(以 WeightedResponseTimeRule 为例)

  1. 定期采集每个实例的请求响应时间;
  2. 响应时间越短,权重越高(公式:权重 = 总响应时间 - 实例响应时间);
  3. 按权重分配请求,确保高性能实例处理更多请求。

3.4 权重调整:动态流量控制与灰度发布

📌 核心概念:权重是 Nacos 提供的「动态流量分配机制」,权重值范围为 0~1,权重越高的实例接收的请求比例越高;权重为 0 时,实例不接收任何请求(用于无感知下线)。

3.4.1 权重调整方式
方式 1:Nacos 控制台调整(推荐,实时生效)

📝 操作步骤

  1. 访问 Nacos 控制台 → 「服务管理」→ 「服务列表」→ 点击 user-service 「详情」;
  2. 在「实例列表」中,找到目标实例,点击「编辑」;
  3. 修改「权重」值(如从 1 改为 0.8),点击「确定」;
  4. 无需重启服务,权重调整实时生效。
方式 2:API 调整(适合自动化脚本)

📝 HTTP API 示例(修改实例权重):

http

PUT http://192.168.222.128:8848/nacos/v1/ns/instance
Content-Type: application/x-www-form-urlencoded

serviceName=user-service&ip=127.0.0.1&port=8091&weight=0.5
3.4.2 权重实战场景
  1. 灰度发布

    • 需求:新版本 userService(v2)上线,先让 10% 流量进入新版本;
    • 操作:新版本实例权重设为 0.1,旧版本实例权重设为 1
    • 验证:观察新版本实例日志,无异常后逐步提高权重至 1,完成全量发布。
  2. 无感知下线

    • 需求:下线 userService91 实例进行维护;
    • 操作:将该实例权重设为 0
    • 效果:实例不再接收新请求,待当前请求处理完毕后,即可安全停机维护。

⚠️ 注意事项:权重调整仅对「基于 Nacos 的负载均衡规则」生效(如 NacosRule、RoundRobinRule),自定义规则需自行实现权重逻辑。

3.5 命名空间隔离:多环境与多租户隔离

📌 核心概念:命名空间(Namespace)是 Nacos 的「强隔离机制」,可用于隔离不同环境(如 dev 开发、test 测试、prod 生产)或不同租户的服务,避免环境间服务相互调用导致的问题。

3.5.1 命名空间核心逻辑

🔍 隔离层级:Nacos 隔离层级为「Namespace → Group → 服务 / 配置」,其中:

  • Namespace:最高层级隔离,用于隔离环境 / 租户;
  • Group:次层级隔离,用于隔离同一环境下的不同业务(如 ORDER_GROUPUSER_GROUP);
  • 服务 / 配置:最底层,属于某个 Group。
3.5.2 命名空间配置实战
步骤 1:创建命名空间(Nacos 控制台)

📝 操作步骤

  1. 访问 Nacos 控制台 → 「命名空间」→ 「新建命名空间」;
  2. 填写信息:
    • 命名空间名称:dev(开发环境);
    • 描述:开发环境专用命名空间
  3. 点击「确定」,记录生成的「命名空间 ID」(如 a2126436-81b4-4d2f-b20f-5487590d381c)。
步骤 2:服务关联命名空间(application.yml)

📝 配置 dev 环境命名空间

yaml

spring:
  cloud:
    nacos:
      discovery:
        namespace: a2126436-81b4-4d2f-b20f-5487590d381c # 填写命名空间 ID(非名称)
步骤 3:验证隔离效果
  • 现象:dev 环境的 order-service 只能发现 dev 环境的 user-service,无法发现 prod 环境的 user-service
  • 结论:命名空间实现「强隔离」,跨命名空间服务无法相互发现和调用。

⚠️ 关键注意:上下游服务(如 order-service 和 user-service)必须配置相同的命名空间 ID,否则无法正常调用;命名空间 ID 是唯一标识,而非名称(名称可重复,ID 不可重复)。

3.6 临时实例与非临时实例:适配不同服务类型

📌 核心差异:实例类型决定了 Nacos 对实例健康状态的检测方式和故障处理逻辑,需根据服务是否有状态选择。

3.6.1 两种实例类型对比
实例类型健康检测方式故障处理逻辑适用场景配置方式
临时实例客户端主动发送心跳(默认 5 秒)超过 30 秒未发心跳 → 标记不健康 → 剔除实例无状态服务(如 API 服务、订单服务)默认(ephemeral: true
非临时实例Nacos Server 主动探测(默认 20 秒)探测失败 → 标记不健康 → 不自动剔除有状态服务(如数据库、Redis、消息队列)ephemeral: false
3.6.2 非临时实例配置实战

📝 application.yml 配置

yaml

spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false # 设为非临时实例
        health-check-url: http://${spring.application.name}:${server.port}/actuator/health # 自定义健康检查地址(可选)

🔍 原理差异

  • 临时实例:依赖客户端心跳维持状态,适合无状态服务(服务重启后实例信息重新注册,不影响数据);
  • 非临时实例:依赖服务端主动探测,适合有状态服务(实例下线后需手动处理数据,避免自动剔除导致数据丢失)。

⚠️ 注意事项:非临时实例下线时,需手动在 Nacos 控制台删除实例或调用 API 注销,否则 Nacos 会一直保留实例信息(标记为不健康)。

四、综合实战:跨服务调用全流程

4.1 场景说明

需求:order-service(端口 8093)调用 user-service(3 个实例:8091/8097/8098,集群 SH)的 /user/getUser/{id} 接口,实现「集群优先 + 权重负载均衡」。

4.2 环境准备

  1. 部署 3 个 user-service 实例(端口 8091/8097/8098,集群 SH,权重均为 1);
  2. 部署 1 个 order-service 实例(端口 8093,集群 SH,负载均衡规则 NacosRule);
  3. user-service 提供 /user/getUser/{id} 接口,返回用户信息和当前实例端口。

4.3 核心代码实现

4.3.1 user-service 接口实现

📝pom.xml:完整配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.shop</groupId>
        <artifactId>spring-cloud-shop</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.shop</groupId>
    <artifactId>user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-service</name>
    <description>user-service</description>

    <dependencies>
        <!-- 1. Web依赖:支持HTTP接口开发(如@RestController、@RequestMapping) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 2. 数据访问依赖:MyBatis-Plus(ORM框架,简化CRUD) + MySQL驱动(连接MySQL) -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope> <!-- 运行时依赖:编译不依赖,仅启动时加载驱动 -->
        </dependency>

        <!--nacos依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

</project>

📝配置文件:

server:
  port: 8091
spring:
  application:
    name: user-service
  # 配置数据源
  datasource:
    url: jdbc:mysql://192.168.222.128:3307/shop_user?useSSL=false&serverTimezone=UTC
    username: root
    password: abc123

  #配置nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.222.128:8848
        cluster-name: JQ-SZ

📝启动类:参考 2.2.3

📝 UserController.java

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {

    /**     * 用户查询接口     * @param id 用户ID     * @return 用户信息 + 当前实例端口     */
    @GetMapping("/getUser/{id}")
    public String getUser(@PathVariable("id") Long id) {
        // 获取当前实例端口(用于验证负载均衡效果)
        String port = System.getProperty("server.port");
        // 模拟用户信息返回
        return String.format("用户ID:%d,当前服务端口:%s,集群:SH", id, port);
    }
}
4.3.2 order-service 调用实现

📝pom.xml:完整配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.shop</groupId>
        <artifactId>spring-cloud-shop</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.shop</groupId>
    <artifactId>user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-service</name>
    <description>user-service</description>

    <dependencies>
        <!-- 1. Web依赖:支持HTTP接口开发(如@RestController、@RequestMapping) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 2. 数据访问依赖:MyBatis-Plus(ORM框架,简化CRUD) + MySQL驱动(连接MySQL) -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope> <!-- 运行时依赖:编译不依赖,仅启动时加载驱动 -->
        </dependency>

        <!--nacos依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- 负载均衡依赖,支持服务名解析 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

</project>

📝配置文件:

server:
  port: 8093
spring:
  application:
    name: order-service
  # 配置数据源
  datasource:
    url: jdbc:mysql://192.168.222.128:3307/shop_user?useSSL=false&serverTimezone=UTC
    username: root
    password: abc123

  #配置nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.222.128:8848
        cluster-name: JQ-SH
        # namespace: a2126436-81b4-4d2f-b20f-5487590d381c # 命名空间ID,默认public
    loadbalancer:
      nacos:
        enabled: true
user-service: # 服务名,对应user-service的spring.application.name
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

参考 2.3.1

4.4 测试验证与效果观察

4.4.1 负载配置
服务名端口集群
orderService8093JQ-SH
userService918091JQ-SH
userService978097JQ-SH
userService988098JQ-SZ
4.4.2 负载均衡效果验证
  1. 访问 http://localhost:8093/order/create,多次刷新;
  2. 观察返回结果中的「服务端口」,会在 8091/8097 之间切换(符合 NacosRule 集群优先 + 轮询策略),不会访问8098;
  3. 访问 Nacos 控制台 → user-service 实例列表,确认每个实例的请求次数基本均衡。
4.4.3 故障容错验证
  1. 停止 userService91 实例;
  2. 再次访问 http://localhost:8093/order/create
  3. 观察结果:请求会自动分发到 8097 实例,无调用失败(Nacos 自动剔除不健康实例)。
  4. 停止userService97 实例;
  5. 再次访问 http://localhost:8093/order/create
  6. 观察结果:请求会跨集群调用到8098实例,无调用失败;

五、Nacos 服务治理总结与生产实践建议

5.1 核心知识点总结

  1. 服务注册发现流程:服务启动 → 加载 Nacos 配置 → 调用 NacosServiceRegistry.register() 注册实例 → 定期发送心跳维持健康状态;消费者通过 DiscoveryClient 拉取实例列表,结合负载均衡调用服务。
  2. 高可用核心手段:多实例部署(避免单点故障)+ 集群管理(优化延迟)+ 权重调整(动态流量)+ 命名空间隔离(环境隔离),四者结合保障服务稳定。
  3. 实例类型选择:无状态服务用「临时实例」(AP 模式,自动剔除),有状态服务用「非临时实例」(CP 模式,手动管理)。
  4. 负载均衡规则适配:多集群用 NacosRule,实例性能差异大用 WeightedResponseTimeRule,高可用要求高用 RetryRule

5.2 常见问题排查指南

问题现象排查步骤
服务注册不上1. 检查 Nacos Server 地址是否可达;2. 检查服务名是否配置;3. 查看服务日志(是否有注册失败异常)
实例状态不健康1. 检查临时实例是否正常发送心跳;2. 检查非临时实例的健康检查接口是否可用;3. 查看 Nacos 探测日志
服务调用失败1. 检查上下游服务是否在同一命名空间;2. 检查负载均衡规则是否配置正确;3. 检查服务实例是否健康

后续章节预告

本章我们深入讲解了 Nacos 的「服务治理」核心能力,从基础的服务注册发现,到高级的集群、权重、隔离特性,覆盖了微服务服务治理的全场景。

下一章,我们将聚焦 Nacos 的另一大核心功能 ——Nacos 配置中心,重点学习:

  1. 配置中心的核心价值:如何解决「配置分散」「更新需重启」等问题;
  2. 实战步骤:从 Nacos 控制台创建配置、服务拉取配置,到动态配置刷新(无需重启服务);
  3. 高级特性:多环境配置(dev/test/prod)、配置加密(敏感信息保护);
  4. 生产实践:配置优先级、灰度发布、配置回滚、与 Spring Cloud Config 的对比。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值