Nacos 详细配置操作(解决首次调用慢问题)

以下操作基于 Spring Cloud Alibaba + Nacos 环境,分「客户端配置(调用方)」和「服务端优化(可选)」两部分,每一步都有具体代码/配置和操作说明,新手也能直接照搬。

问题

为什么第一次调用远程服务,耗时40秒,怎么调优

在这里插入图片描述
在这里插入图片描述

一、核心目标

通过 Nacos 配置优化,减少首次调用时的服务发现开销,具体解决:

  1. 首次调用无需重复订阅服务
  2. 复用服务实例缓存,避免重复拉取
  3. 减少连接建立耗时

二、前置准备

确认项目依赖(已集成可跳过)
首先确保 pom.xml 中引入了 Nacos 服务发现依赖(Spring Cloud Alibaba 版本需与 Spring Boot 匹配,比如 Spring Boot 2.7.x 对应 Spring Cloud Alibaba 2021.0.5.0):

<!-- Nacos 服务发现依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.0.5.0</version> <!-- 按实际版本调整 -->
</dependency>

三、客户端配置(调用方,关键步骤)

所有配置均在调用方(你的微服务,端口 36666)的 application.ymlapplication.properties 中配置,以下以 yml 为例。

1. 基础服务发现配置(必配)

先配置 Nacos 服务器地址、服务名等基础信息,确保能正常注册发现:

spring:
  application:
    name: your-service-name # 你的服务名(比如 device-service)
  cloud:
    nacos:
      discovery:
        # 1. Nacos 服务器地址(单机填 IP:端口,集群填多个地址用逗号分隔)
        server-addr: 192.168.152.1:8848 # 替换成你的 Nacos 地址(默认端口 8848)
        # 2. 命名空间(如果没创建,默认是 public,填命名空间 ID 不是名称)
        namespace: public # 或你的命名空间 ID(比如 dev 的 ID)
        # 3. 分组(默认 DEFAULT_GROUP,和被调用方 zgb-system 保持一致)
        group: DEFAULT_GROUP
        # 4. 元数据(可选,标记服务来源)
        metadata:
          preserved.register.source: SPRING_CLOUD

2. 优化服务缓存与订阅策略(核心,解决首次慢)

添加以下配置,减少服务实例拉取和订阅的开销:

spring:
  cloud:
    nacos:
      discovery:
        # 5. 服务实例缓存时间(单位:毫秒,默认 10000ms=10秒,延长到 300 秒)
        # 作用:首次拉取服务实例后,本地缓存 5 分钟,期间不重复向 Nacos 拉取
        cache-timeout: 300000 # 5分钟(根据业务调整,建议 300-600 秒)
        # 6. 禁用主动刷新服务列表(默认 true,改为 false,依赖缓存+Nacos 推送)
        # 作用:避免定时主动拉取,改为只接收 Nacos 服务器的推送更新(更高效)
        enable-auto-refresh: false
        # 7. GRPC 订阅配置(默认已启用,优化连接复用)
        # 保持 GRPC 连接复用,减少重连开销(无需手动改,默认配置即可)
        grpc:
          enable: true # 默认 true,启用 GRPC 订阅(比 HTTP 订阅更快)
          keep-alive-time: 30000 # GRPC 连接保活时间(30秒)
          keep-alive-timeout: 10000 # 保活超时时间(10秒)

3. 连接池优化(复用 Nacos 客户端连接)

Nacos 客户端底层用 GRPC/HTTP 连接,优化连接池参数,避免首次创建连接耗时:

# Nacos 客户端公共配置(独立于 discovery 节点)
nacos:
  client:
    # GRPC 连接池配置(Nacos 2.x+ 支持)
    grpc:
      core-pool-size: 10 # 核心线程池大小(默认 5,调整为 10)
      max-pool-size: 30 # 最大线程池大小(默认 20,调整为 30)
      keep-alive-time: 60 # 线程空闲保活时间(60秒)
    # HTTP 连接池配置(兼容老版本 HTTP 订阅)
    http:
      max-connections: 100 # 最大连接数(默认 50,调整为 100)
      connection-timeout: 3000 # 连接超时时间(3秒,默认 5秒,缩短超时)
      read-timeout: 5000 # 读取超时时间(5秒)

4. 禁用不必要的日志(可选,减少日志开销)

Nacos 默认订阅日志较多,可调整日志级别,避免日志打印耗时(在 logback.xmllog4j2.xml 中配置):

<!-- logback.xml 示例 -->
<logger name="com.alibaba.nacos.client.naming" level="WARN" /> <!-- 订阅日志改为 WARN 级别 -->
<logger name="com.alibaba.nacos.client.remote" level="WARN" /> <!-- GRPC 日志改为 WARN 级别 -->

四、服务端优化(可选,Nacos 服务器配置)

如果能操作 Nacos 服务器(部署 zgb-system 和 Nacos 的机器),可进一步优化,减少服务端响应耗时:

1. 调整 Nacos 服务端缓存(单机模式)

编辑 Nacos 服务器的 conf/application.properties 文件,添加以下配置:

# 1. 服务实例缓存过期时间(默认 30 秒,延长到 5 分钟)
nacos.naming.instance.cache.expire.seconds=300
# 2. 禁用服务实例健康检查(如果 zgb-system 是稳定服务,无需频繁检查)
# 注意:如果服务可能下线,不建议禁用,改为调整检查间隔
nacos.naming.health.check.enable=false
# 3. 调整健康检查间隔(如果不禁用健康检查)
nacos.naming.health.check.interval=60000 # 60秒检查一次

2. 集群模式优化(如果 Nacos 是集群)

如果 Nacos 是集群部署,确保:

  1. 集群节点之间网络通畅,避免数据同步延迟
  2. 启用集群缓存同步:在 conf/cluster.conf 中配置所有节点地址,确保数据一致性

五、关键操作步骤总结(按顺序执行)

  1. 确认依赖:调用方项目已引入 Nacos 服务发现依赖
  2. 配置客户端:在调用方 application.yml 中添加「基础配置+缓存+连接池」配置
  3. 优化日志:调整 Nacos 客户端日志级别为 WARN(可选)
  4. 重启服务:重启调用方微服务(36666 端口的服务)
  5. 验证配置:启动后查看日志,确认以下信息(说明配置生效):
    • 日志中不再频繁出现 [subscribe,164] 订阅日志(仅启动时出现一次)
    • 日志中 [processServiceInfo,144] 显示服务实例从缓存中获取(而非重复拉取)

六、验证效果

配置完成后,测试两次调用:

  1. 首次调用:耗时应从 40 秒大幅降低(一般到 1-3 秒,取决于网络和 zgb-system 响应)
  2. 第二次调用:耗时应在 100ms 以内(复用缓存和连接)
  3. 查看日志:首次调用后,后续调用不再出现 Nacos 订阅和 IP 初始化日志

七、常见问题排查

  1. 配置不生效
    • 检查 namespace 是否填对(必须填命名空间 ID,不是名称!在 Nacos 控制台「命名空间」中查看 ID)
    • 检查 group 是否和 zgb-system 一致(zgb-system 注册时的 group 是 DEFAULT_GROUP,调用方必须相同)
  2. 首次调用仍慢
    • 检查 Nacos 服务器地址是否正确(是否能 ping 通,端口 8848 是否开放)
    • 检查 zgb-system 服务是否已注册到 Nacos(在 Nacos 控制台「服务列表」中查看是否有 zgb-system 实例)
  3. 缓存过期后调用变慢
    • 若业务允许,可进一步延长 cache-timeout(比如 10 分钟)
    • 结合调用方的服务预热(之前提到的主动触发空请求),提前刷新缓存

八、补充:配合服务预热(彻底解决冷启动)

Nacos 配置优化后,首次调用的主要开销已解决,但仍可能存在 Feign 代理初始化、zgb-system 服务自身冷启动的问题。可在调用方添加「服务预热」代码,启动后主动触发一次空请求:

1. 添加预热组件(Spring Boot 启动后执行)

创建一个 ServiceWarmup.java 类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class ServiceWarmup implements CommandLineRunner {

    // 注入你的远程调用接口(或 RestTemplate)
    @Autowired
    private RemoteFirmwareVersionService remoteFirmwareVersionService;

    @Override
    public void run(String... args) throws Exception {
        // 启动后延迟 3 秒执行预热(避免服务未完全启动)
        Thread.sleep(3000);
        try {
            // 发送一次空请求(或模拟产品 ID 的请求),触发服务发现和连接建立
            log.info("开始服务预热,调用 zgb-system 接口");
            remoteFirmwareVersionService.queryByProductId(); // 实际调用接口(如果需要传参,传一个无效参数或默认参数)
            log.info("服务预热完成");
        } catch (Exception e) {
            log.warn("服务预热失败,不影响后续正常调用", e);
        }
    }
}

2. 效果

启动微服务后,会自动触发一次远程调用,完成 Nacos 服务订阅、连接建立、Feign 初始化。后续业务调用时,直接复用已有资源,首次业务调用耗时和第二次基本一致。

通过以上 Nacos 配置 + 服务预热,就能彻底解决「首次调用慢,第二次快」的问题!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐