惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
GRAHAM CLULEY
V
V2EX
WordPress大学
WordPress大学
博客园 - Franky
Last Week in AI
Last Week in AI
博客园 - 司徒正美
有赞技术团队
有赞技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
V
Visual Studio Blog
C
CERT Recently Published Vulnerability Notes
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
腾讯CDC
The Hacker News
The Hacker News
Hugging Face - Blog
Hugging Face - Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
J
Java Code Geeks
人人都是产品经理
人人都是产品经理
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
A
Arctic Wolf
量子位
博客园 - 聂微东
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
News and Events Feed by Topic
雷峰网
雷峰网
博客园_首页
Google Online Security Blog
Google Online Security Blog
Spread Privacy
Spread Privacy
罗磊的独立博客
H
Hacker News: Front Page
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
TaoSecurity Blog
TaoSecurity Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
IT之家
IT之家
The Cloudflare Blog
爱范儿
爱范儿
博客园 - 叶小钗
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - 郭慕荣

彻底搞懂 Codex Skill 与插件:区别、试用、核心作用、项目落地全指南(程序员实战向) Codex Skill 和插件到底有什么区别?程序员如何在项目中落地使用 claudecode 配置防止配置文件泄露总结 Claude code分析外部文件总结 Claude code三种模式详解 hasCompletedOnboarding详解 Claudecode 有哪些常用的命令 claude.md文件详解 claude code 的setting文件详解 Docker部署zookeeper总结 Mac中git ssh的配置(GitLab) Java 类加载机制 面试题(一) 如何监控和调优JVM性能? jvm常用的参数有哪些? 怎么配置? hashmap 和currenthashmap 的原理?详解一下 aop在项目中使用的场景?怎么使用? Java dubbo spring springboot中的spi机制 spring中常见的两种代理模式 Redis的zset 面试汇总 drools 规则引擎在线化配置 springcloud中常用的注解详解 springcloud中网关gateway总结 spring是怎么解决循环依赖的? MySQL 死锁 怎么处理? 在写left join的时候 是大表在左侧 还是小表在左侧(二) 在写left join的时候 是大表在左侧 还是小表在左侧(一) nacos客户端(接口调用者)如何感知被调用服务下线?(一) 在MySQL中 redolog undolog binlog 写入的场景,顺序
nacos客户端(接口调用者)如何感知被调用服务下线? (二)
郭慕荣 · 2025-10-18 · via 博客园 - 郭慕荣

🧩 一、问题背景

场景:
你有两个微服务:

  • order-service(调用方 / Consumer)

  • product-service(被调用方 / Provider)

product-service 的一个实例下线(比如机器宕机或应用关闭)时,
order-service 要知道它已经失效,不能再发请求过去。


🧠 二、Nacos 的服务发现机制

Nacos 分为两部分:

  • Naming Server(注册中心)

  • Naming Client(客户端SDK)

Nacos 客户端(如 spring-cloud-starter-alibaba-nacos-discovery)既可以注册自己,也能订阅别人。


📍 服务注册阶段

1️⃣ product-service 启动后向 Nacos Server 注册:

2️⃣ Nacos Server 将这个实例保存到内存和磁盘(临时实例或持久实例)。

3️⃣ 同时,order-service 订阅 product-service 的实例列表。


⚙️ 三、Consumer 如何“感知” Provider 下线?

Nacos 设计了两种机制结合使用:


1️⃣ 心跳检测(Heartbeat Check)

作用:判断服务端实例是否健康

  • 对于 临时实例(ephemeral=true)

    • 服务提供者每 5 秒 向 Nacos Server 发送心跳包。

    • 如果超过 15 秒未收到心跳,Nacos Server 将认为该实例“下线”。

    • Nacos Server 会从注册表中移除该实例。

示例日志:


2️⃣ 推送机制(Push)+ 客户端本地缓存

当服务实例变化(新增、下线、心跳失效)时:

✅ Nacos Server 会主动推送变更事件给客户端

Nacos 使用的是 长轮询(Long Polling) 机制,而不是短轮询。

流程如下:

  1. order-service 客户端启动后,向 Nacos Server 发起一个 长轮询请求

  2. 这个请求会阻塞 30 秒左右

  3. 如果在这期间 product-service 的实例列表发生变化(新增/下线):

    • Nacos Server 会立即返回变化数据。

  4. 客户端收到更新后:

    • 更新本地缓存(本地注册表)

    • 通知负载均衡组件(Ribbon / LoadBalancer)

  5. 客户端再发起新的长轮询请求,如此循环。

所以客户端能在几十毫秒到几秒内感知实例变化,而不是实时心跳。


🧭 四、调用方的负载均衡逻辑

Spring Cloud Alibaba 集成了 NacosDiscoveryClient + Spring LoadBalancer

  1. 每个服务都有本地的实例列表缓存。

  2. 当实例变化时(Server 推送事件),本地缓存更新。

  3. 下次发起 HTTP 调用时,会从最新缓存中选取健康实例。

所以:

  • 当服务下线 → 心跳超时 → Nacos 推送 → 本地缓存刷新 → 下次调用自动避开无效节点。


🔄 五、完整交互流程图


📊 六、延迟感知与优化建议

优化点描述
心跳频率 默认 5 秒,可根据实际 SLA 调整(推荐 3~5s)
心跳超时时间 默认 15 秒,可调低(如 10s)以更快下线检测
客户端缓存刷新间隔 客户端一般在 5s 内完成更新
推送机制优化 使用 nacos.naming.push.empty.protection=false 保证推送异常时重试
自定义健康检查 在 Provider 中暴露 /health,由 Nacos 定时检测应用层健康状态

💡 七、总结记忆口诀

“Provider 发心跳,Server 记健康,Consumer 长轮询,缓存自动换。”

环节主体机制作用
健康检测 Provider → Server 心跳包 让 Nacos 知道谁活着
状态维护 Server 注册表维护 标记实例 UP/DOWN
事件推送 Server → Consumer 长轮询推送 通知调用方更新实例列表
调用选择 Consumer 本地缓存 + 负载均衡 自动选择健康实例调用