在 Nacos 点了下线,为什么流量还是打到了停机的机器上?
前两天面试问了一个非常日常的问题❝你们线上发版的时候怎么保证旧服务下线时用户的请求不报错他挺自信地回答这很简单啊去 Nacos 控制台找到那个实例点一下下线按钮。或者在发布脚本里直接kill -15杀进程Nacos 收不到心跳自然就把节点剔除了网关就不会往这台机器发流量了。额在真实的生产环境下如果发布流水线真的只是这么干那每次发版的一两分钟里你们的网关日志里一定会刷出一堆Connection Refused或者Read Timeout的报错。如果刚好赶上晚高峰用户的直观体验就是点了一下按钮界面弹出一个醒目的网络异常。1. 流量为什么停不住很多同学对注册中心有一个误解觉得它是一个绝对实时的系统只要 Nacos 知道某个节点下线了所有依赖的微服务就瞬间都知道了。但在分布式系统里信息的传递是需要时间的。服务调用方比如 Gateway 网关在发起 HTTP 请求前需要知道目标服务的 IP。但为了性能网关不可能每来一个请求都去 Nacos 查一次网络。会用像 Ribbon 或者 SpringCloud LoadBalancer 这样的客户端负载均衡组件会在自己的内存里维护一个ServerList 服务 IP 列表缓存。坑就踩在这个缓存的更新机制上调用方默认会启动一个后台定时任务每隔一段时间去 Nacos 拉取最新的实例列表。虽然 Nacos 服务端也有 UDP 实时推送变更的机制但在复杂的生产网络里UDP 推送是有概率丢失的。这就导致了一个长达几十秒的时间差。在这几十秒里虽然 Nacos 服务端已经把那个节点标记为下线了但网关本地的缓存还没刷新网关手里拿着的依然是旧名单。现在回想一下你在控制台点下线后的操作你调用了下线紧接着就触发了重启进程被杀掉。但此时网关还没更新缓存依然把用户的请求往这台已经死掉的机器上送。操作系统一看端口都没人监听了直接回一个 RST 包网关马上就报Connection Refused了。2. 中小团队的解法知道了原因解决思路也就有了。很多中小团队的做法是在 CI/CD 发布流水线里加一行sleep 40。流程变成了这样主动摘流,脚本先调 Nacos 的 OpenAPI把机器标记为下线。脚本强行sleep 40秒。在这 40 秒里机器还在正常运行依然在处理请求只是我们在这 40 秒里等待全网所有的网关更新完缓存。优雅停机40 秒一过没人往这发请求了再发送kill -15杀进程。这套方案确实管用。但如果你拿着这个方案去大厂面试依然是不及格的。原因很简单太慢了且不具备普适性。如果一个核心服务有 500 个节点滚动发布时每个节点都要干等 40 秒发一次版要好几个小时。而且单纯靠等根本无法应对物理机突然宕机、网络抖动等突发情况因为机器意外宕机时你根本没机会去 sleep。3. 大厂的无损下线方案第一步编排层摘流正规一点的公司下线动作不该由 Jenkins 脚本控制而应该与 K8s 的 Pod 生命周期深度绑定。当 K8s 决定缩容或更新一个 Pod 时它不会立刻发送kill -15而是会先触发一个生命周期前置钩子PreStop Hook。在 K8s 的 yaml 里这么写lifecycle: preStop: exec: command: - /bin/sh - -c - | # 1. 立即向 Nacos 发送下线请求主动摘除自己 curl -X PUT http://nacos-server:8848/nacos/v1/ns/instance?serviceNamemy-serviceip${POD_IP}port8080enabledfalse # 2. 象征性地短暂停顿 3~5 秒给 Nacos 的 UDP 主动推送一点时间 sleep 5这一步把主动下线的逻辑封装在了容器内部只要 Pod 要死临死前第一件事就是去注册中心销户。第二步客户端重试即使有 PreStop依然无法 100% 避免在那几秒钟里有残余的请求顺着网关的旧缓存打过来。当这台机器停止接收新请求时网关打过来的请求会立刻收到操作系统的Connection Refused。注意这个极其关键的细节ConnectException发生在 TCP 三次握手阶段此时 HTTP 业务数据根本还没有发出去既然业务没执行那这个请求就是绝对安全、绝对幂等的。所以我们在网关或上游微服务里必须开启底层的重试机制。以 SpringCloud 为例只要加上spring: cloud: loadbalancer: retry: enabled: true # 开启客户端重试此时发生的奇迹是网关拿着旧 IP 发请求 - 碰壁报错Connection Refused-网关底层的 LoadBalancer 捕获到连接异常默默把它掐掉然后自动从缓存里换另外一个健康的 IP 重新发起请求。整个过程在几毫秒内完成最终用户在手机上看到的就是一个正常的 200 OK用户是无感知的。第三步应用的优雅停机有了前面两步进入这台机器的新请求已经被完美挡住并重试了。最后是处理那些已经接进来了正在工作的老请求。在 Spring Boot 项目的application.yml里加上这两行配置server: shutdown: graceful # 开启优雅停机 spring: lifecycle: timeout-per-shutdown-phase: 30s # 最多等老请求 30 秒配合 K8s 的停机机制Java 进程在等待一段时间后然后彻底释放资源。4. 无损下线全流程为了让你看得更直观我画了这张涵盖了K8s Nacos 客户端重试的联动时序图。

相关新闻

BeeWorks底座:私有化IM、丰富模块与强集成能力的企业协作平台

BeeWorks底座:私有化IM、丰富模块与强集成能力的企业协作平台

一、核心结论:BeeWorks不是单一聊天工具,而是企业协作底座BeeWorks的核心定位不是“再做一个企业聊天软件”,而是为企业提供一个可私有化部署、可集成、可定制、可扩展的数字化协作底座。它以私有化IM为入口,向上承载文档中心、多…

2026/7/23 7:29:42阅读更多 →
别再手写Prompt了!LangChain模板实战指南,3个案例带你从入门到业务落地

别再手写Prompt了!LangChain模板实战指南,3个案例带你从入门到业务落地

1. 本章目标学完本章后,你应该能够:理解 Prompt 在大模型应用中的作用使用普通字符串编写 Prompt使用 PromptTemplate 管理单段提示词使用 ChatPromptTemplate 管理聊天消息给 Prompt 注入变量编写适合业务场景的提示词完成商品文案、学习计划、客服回复…

2026/7/23 7:29:42阅读更多 →
Chrome启动参数详解:提升开发调试效率的实用指南

Chrome启动参数详解:提升开发调试效率的实用指南

1. Chrome启动参数概述Chrome浏览器提供了丰富的启动参数,这些参数可以精确控制浏览器的各种行为和功能。作为一名长期使用Chrome的前端开发者,我发现合理使用这些参数能极大提升开发效率和调试体验。启动参数主要通过命令行方式传递,格式为c…

2026/7/23 7:29:42阅读更多 →
Hive sql 进阶题 03

Hive sql 进阶题 03

用户注册、登录、下单综合统计从用户登录明细表(user_login_detail)和订单信息表(order_info)中查询每个用户的注册日期(首次登录日期)、总登录次数以及其在2021年的登录次数、订单数和订单总额。select t1…

2026/7/23 9:06:11阅读更多 →
数字资源管理技术实践:从PDF处理到全文检索的完整解决方案

数字资源管理技术实践:从PDF处理到全文检索的完整解决方案

《半月谈》杂志2018-2025年合集:技术视角下的数字资源管理与应用指南 在信息爆炸的时代,如何高效获取、整理和利用高质量的数字资源成为技术人员面临的重要课题。近期不少开发者询问《半月谈》这类权威期刊的数字资源获取与处理方法,本文将系…

2026/7/23 9:06:11阅读更多 →
如何制定合理的装修预算方案?

如何制定合理的装修预算方案?

在制定装修预算时,开始需要对自己的需求有清晰的认识。这包括对房间布局、功能需求的明确,以及对装修风格的基本构想。制定预算方案时,可以从轻工辅料、水电改造和主材三个主要方面入手。轻工辅料是指在装修中必不可少的材料,如涂…

2026/7/23 9:06:11阅读更多 →
Python斗兽棋双模式开发:从MVC架构到游戏逻辑实现

Python斗兽棋双模式开发:从MVC架构到游戏逻辑实现

1. 项目概述:为什么选择Python重构经典斗兽棋?最近在整理旧项目时,翻到了一个用Python写的斗兽棋游戏。这可不是一个简单的课后作业,而是一个同时支持图形界面(GUI)和纯命令行(CLI)两…

2026/7/23 9:06:11阅读更多 →
深入解析C++ vector扩容机制:从原理到性能优化实践

深入解析C++ vector扩容机制:从原理到性能优化实践

1. 项目概述:为什么我们需要关心vector的扩容?如果你写过C,几乎不可能没用过std::vector。它就像我们口袋里的瑞士军刀,简单、顺手,能装下各种类型的数据。但不知道你有没有遇到过这样的场景:程序跑得好好的…

2026/7/23 9:06:11阅读更多 →
TMS470 ARM7开发套件快速入门:从环境搭建到LED闪烁实战

TMS470 ARM7开发套件快速入门:从环境搭建到LED闪烁实战

1. 从零到一:TMS470 IAR KickStart套件开箱与初体验 如果你刚拿到TI的TMS-FET470A256 IAR KickStart开发套件,面对一堆板卡、线缆和光盘,可能会有点无从下手。别担心,这几乎是每个嵌入式工程师的必经之路。我当年第一次接触TMS470…

2026/7/23 9:04:10阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/23 0:56:31阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/23 0:56:31阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 0:56:31阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:00:28阅读更多 →
从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:28阅读更多 →
油泥处理设备哪里能买到

油泥处理设备哪里能买到

油泥处理设备哪里有?这是许多从事油田、炼化、清罐业务的从业者最关心的问题。根据河南三丰环保设备有限公司的行业经验,选购油泥处理设备的核心在于设备能否适配当地环保法规与原料特性,而非单纯看价格。该公司总经理王钦田先生指出&#xf…

2026/7/23 0:00:28阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/22 22:56:18阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/22 18:55:50阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/22 18:55:50阅读更多 →