前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Node.js SIGTERM graceful shutdown 优雅停机
NoNode.js服务端工程

Node.js 收到 SIGTERM 后怎样设计有截止时间的优雅停机?

优雅停机需要整个请求链路配合,单独注册一个信号监听器无法保证所有请求都完成。

前端进阶之旅 · 一题精讲更新于 2026.09.06
Node.js#服务端工程
先看核心答案
理解线索

把停机拆成可观察的状态

  1. 撤下流量标记 draining 并让入口停止分配新工作
  2. 等待完成跟踪已有请求与任务,在期限内收敛
  3. 回收退出依次释放资源,对逾期工作执行既定策略

就绪状态传播不是瞬时完成。已有连接、代理缓存和在途请求都可能跨过状态切换,需要在应用与入口两侧一起验证。

核心回答

先记住这个答案

收到 SIGTERM 后先进入幂等的 draining 状态,协调流量入口撤下就绪状态,并停止接受新连接和新任务,再在明确截止时间内等待已有请求与关键作业结束,随后按依赖顺序关闭连接池等资源。Node 的信号监听器会改变默认退出行为,因此必须自己保证流程能结束。到期仍未完成的连接需要明确强制处理,WebSocket 等升级连接也要单独管理。部署平台可能最终强杀,网络和客户端也会失败,所以应结合幂等、重试和可恢复任务降低损失,而非保证绝不丢请求。

  • 接管信号后必须负责退出完成条件
  • 排空、停止后台任务和关闭依赖有先后关系
  • 截止时间必须短于外部平台的强杀期限

先定义哪些工作算完成

HTTP 响应结束、数据库提交和后台消息确认可能是三个不同时间点。停机计数应对应业务承诺,不能只看到 socket 数归零就假定所有异步写入和作业都已完成。

例如下单接口若在发送响应后仍异步写关键状态,排空 HTTP 并不能保护这段工作。应调整事务与响应边界,或把可靠后续处理交给有持久化确认的任务系统,再明确停机时停止领取与归还任务的规则。

用单次状态转换处理信号和并发

多个 SIGTERM 或 SIGINT 可能连续到达,关闭函数应只启动一次,并让后续触发复用同一个完成状态。否则重复关闭连接池、重复释放锁或多次改退出码,会使偶发停机故障难以复现。

开始 draining 后调用 server.close 停止接收新连接,同时与反向代理的摘流时机配合。仍在处理的请求需要保留可用依赖,不能一收到信号就先关闭数据库,再要求这些请求正常完成。

为永不完成的资源设置明确上限

长轮询、SSE、WebSocket、失联下游或卡住的后台任务都可能让等待没有尽头。给各类资源定义停止通知与截止行为,统一总期限,并记录哪些工作在到期后被中断。

正常排空后应取消兜底定时器,释放剩余句柄并让进程结束;到期则执行约定的强制终止策略。应用内定时器也无法抢占同步死循环,因此外部进程管理器仍需拥有最终强杀与重启能力。

回答前,多想一步

容易答错的地方

收到信号立刻 process.exit(0)
这会直接中断仍在执行的请求和异步清理,退出码还可能掩盖未完成工作。应先进入停机流程,正常完成后结束;若必须强制退出,记录触发条件并采用能反映结果的状态。
把不丢请求当作单机函数能实现的保证
代理摘流延迟、客户端断开和平台强杀都超出一个函数的控制范围。需要通过可重试接口、幂等键、持久任务与真实发布演练降低影响,并监测停机期间失败和重复执行。
试着用自己的话回答

面试官还会怎么问?

SIGKILL 能做同样的清理吗?

不能依赖进程捕获或处理 SIGKILL,所以持久状态不能等到最后信号才保存。优雅流程只利用可协商的时间窗口,关键数据仍需在正常执行路径里建立可靠提交和恢复机制。

为什么数据库池要晚一点关?

已有请求可能还需要数据库完成事务或读取结果。过早关闭池会让本可完成的请求失败,应先停止新工作并等待依赖它的工作结束,再关闭池,同时让整个等待受总期限控制。

测试停机时只看退出码够吗?

不够,还要持续发送受控请求,覆盖长请求、后台任务和重复信号,记录完成、失败与重试结果。退出码说明进程最终状态,不能证明客户端收到了响应或某笔业务只执行了一次。

从一道题,走向一组知识

把知识连起来

服务端工程

Node.js 的 close、closeIdleConnections 和 closeAllConnections 有何区别?

选择排空与强制关闭时真正需要的连接操作。

服务端工程

Node.js 触发 uncaughtException 后,为什么不应继续正常接请求?

区分正常发布停机与状态不可信的致命异常。

进程与线程

spawnSync、execSync 在 Node.js 中什么场景适合使用?

理解同步阻塞为何会影响应用内截止时间。

参考资料

  • Node.js 22:信号事件与退出
  • Node.js 22:HTTP 连接关闭

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 先定义哪些工作算完成
  3. 用单次状态转换处理信号和并发
  4. 为永不完成的资源设置明确上限
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑