Node.js 接收 SIGTERM 信号后怎么等待异步任务完成再优雅退出?

文章导读
Node.js 接收 SIGTERM 信号后优雅退出的核心在于监听进程信号事件,并在回调中停止接收新连接、等待现有异步任务完成后再关闭进程。具体步骤包括:使用 process.on('SIGTERM') 注册监听器,在回调中调用 server.close() 停止 HTTP 服务器接受新请求,同时关闭数据库连接、任务队列等资源。必须确保所有异步操作(如请求处理、数据库写入)结束后再调用 proce
📋 目录
  1. Node.js 优雅关闭完整指南:信号处理与资源清理的终极实践
  2. Node.js 任务队列优雅关闭终极指南:确保 Kue 工作进程安全退出
  3. 优雅处理退出信号:在 Node.js 中管理 SIGHUP、SIGINT 和 SIGTERM
  4. 如何让 nodejs 服务器优雅地退出 - 腾讯云开发者社区 - 腾讯云
  5. 如何让 nodejs 服务器优雅地退出
  6. FAQ
A A

Node.js 接收 SIGTERM 信号后优雅退出的核心在于监听进程信号事件,并在回调中停止接收新连接、等待现有异步任务完成后再关闭进程。具体步骤包括:使用 process.on('SIGTERM') 注册监听器,在回调中调用 server.close() 停止 HTTP 服务器接受新请求,同时关闭数据库连接、任务队列等资源。必须确保所有异步操作(如请求处理、数据库写入)结束后再调用 process.exit(0),避免强制终止导致数据不一致或服务中断。在 Docker 或 PM2 环境下,还需注意信号传递机制,确保 Node 进程能直接接收到信号。

Node.js 优雅关闭完整指南:信号处理与资源清理的终极实践

Node.js 优雅关闭流程 实现优雅关闭的核心步骤 1. 正确捕获系统信号 Node.js 进程默认会忽略 SIGTERM 信号,需要显式注册处理函数:process.on('SIGTERM',() =>{ console.log('SIGTERM signal received: closing HTTP server') server.close(() =>{ console.log('HTTP server closed') // 关闭数据库连接等资源 mongoose.connection.close(false,() =>{ console.log('MongoDB connection closed') process.exit(0) }) }) }) javascript 运行 2. 避免信号转发陷阱 使用 npm start 启动应用会导致信号无法正确传递到 Node.js 进程:# 错误示例 CMD ["npm", "start"] # npm 作为父进程会吞噬 SIGTERM 信号 dockerfile 正确做法是直接启动 Node 进程:# 正确示例 CMD ["node", "server.js"] # Node 进程直接接收系统信号(截至 2026 年 3 月 2 日)

Node.js 任务队列优雅关闭终极指南:确保 Kue 工作进程安全退出

1. 监听系统退出信号 在生产环境中,我们需要监听系统发送的退出信号 (如 SIGINT、SIGTERM),并触发 Kue 的关闭流程:// 监听 SIGINT 信号 (Ctrl+C) process.on('SIGINT',function() { console.log('Received SIGINT, shutting down'); jobs.shutdown(function(err) { console.log('Kue shutdown complete'); process.exit(err ?1:0); }); }); // 监听 SIGTERM 信号 (kill 命令) process.on('SIGTERM',function() { console.log('Received SIGTERM, shutting down'); jobs.shutdown(function(err) { console.log('Kue shutdown complete');(2026 年 2 月 27 日)

优雅处理退出信号:在 Node.js 中管理 SIGHUP、SIGINT 和 SIGTERM

1.SIGHUP(Hang Up) 用途:通常在终端断开连接时发送给进程。它最初用于通知守护进程重新加载配置文件。常见场景:当用户通过 SSH 连接到服务器并在远程终端上运行一个长时间运行的进程时,如果 SSH 连接中断,系统会向该进程发送 SIGHUP 信号。守护进程 (如某些服务或后台任务) 可以使用 SIGHUP 来重新加载配置文件而不重启整个进程。2.SIGINT(Interrupt) 用途:当用户按下 Ctrl+C 时发送。通常用于中断进程。常见场景:在命令行界面中运行一个程序时,用户可以通过按下 Ctrl+C 发送 SIGINT 信号来终止该程序。这是一个常见的信号,用于请求程序立即停止当前操作并退出。3.SIGTERM(Terminate) 用途:由进程终止命令 (如 kill 命令) 发送。它请求进程正常终止。常见场景:当你需要停止一个正在运行的进程时,可以使用 kill 命令发送 SIGTERM 信号。进程接收到 SIGTERM 信号后,应该进行清理工作 (如关闭数据库连接、保存状态等),然后退出。处理信号的最佳实践 为了确保应用程序能够优雅地处理这些信号,你应该在代码中监听并处理它们。以下是如何在 Node.js 中实现这一点的示例。示例代码 以下是一个完整的示例,展示了如何在 Node.js 应用程序中监听和处理 SIGHUP、SIGINT 和 SIGTERM 信号,并确保在退出时正确关闭数据库连接。(来自 2025 年 3 月 6 日的资料)

如何让 nodejs 服务器优雅地退出 - 腾讯云开发者社区 - 腾讯云

node.js 服务器优雅退出有哪些关键步骤?怎样确保 nodejs 服务器在退出前完成所有任务?假设我们启动了一个 服务器,接收到了一些客户端的请求,这时候,如果我们想修改一个代码发布,需要重启服务器,怎么办?假设我们有以下代码。server.js 代码语言:javascript ai 代码解释 const net = require ( 'net' ) ; const server = net . createserver ( ) . listen ( 80 ) ; client.js 代码语言:javascript ai 代码解释 const net = require ( 'net' ) ; net . connect ( { port : 80 } ) 如果我们直接杀死进程,那么存量的请求就会无法正常被处理。这会影响我们的服务质量。本文介绍如何使 nodejs 在重启时优雅地退出,所谓优雅,即让 nodejs 进程处理完存量请求后再退出。这关键的地方在于 nodejs 提供的 api server.close().我们看一下这 api 的介绍。代码语言:javascript ai 代码解释 stops the server from accepting new connections and keeps existing connections . this function is asynchronous , the server is finally closed when all connections are ended and the server emits a(该信息的时间戳是 2020 年 11 月 10 日)

如何让 nodejs 服务器优雅地退出

本文介绍如何使 nodejs 在重启时优雅地退出,所谓优雅,即让 nodejs 进程处理完存量请求后再退出。这关键的地方在于 nodejs 提供的 api server.close()。我们看一下这 api 的介绍。Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event. The optional callback will be called once the 'close' event occurs. Unlike that event, it will be called with an Error as its only argument if the server was not open when it was closed. 当我们使用 close 关闭一个 server 时,server 会等所有的连接关闭后才会触发 close 事件。我们看一下源码。Server.prototype.close = function(cb) { // 触发回调 if (typeof cb === 'function') { if (!this._handle) { this.once('close', function close() { cb(new errors.Error('ERR_SERVER_NOT_RUNNING')); }); } else { this.once('close', cb); } } // 关闭底层资源 if (this._handle) { this._handle.close(); this._handle = null; } // 判断是否需要立刻触发 close 事件 this._emitCloseIfDrained(); return this; }; // server 下的连接都 close 后触发 server 的 close 事件 Server.prototype._emitCloseIfDrained = function() { // 还有连接则先不处理 if (this._handle || this._connections) { return; } const asyncId = this._handle ? this[async_id_symbol] : null; nextTick(asyncId, emitCloseNT, this); }; Socket.prototype._destroy = function(exception, cb) { // socket 所属的 server if (this._server) { // server 下的连接数减一 this._server._connections--; // 是否需要触发 server 的 close 事件,当所有的连接 (socket) 都关闭时才触发 server 的是 close 事件 if (this.(撰于 2020 年 11 月 6 日)

FAQ

问:为什么直接 kill 进程会导致服务问题?

Node.js 接收 SIGTERM 信号后怎么等待异步任务完成再优雅退出?

答:因为直接杀死进程会导致存量的请求无法正常被处理,这会影响服务质量,优雅退出可以让进程处理完存量请求后再退出。

问:server.close() 的具体作用是什么?

答:server.close() 会停止服务器接受新连接并保持现有连接,这是一个异步函数,当所有连接结束时服务器最终关闭并触发'close'事件。

问:Docker 容器环境下需要注意什么?

答:在 Docker 容器中实践时发现容器停掉时服务进程并没有接收到 SIGTERM 信号,然后随着容器的销毁服务进程也被强制 kill 了,显然当前正在处理的链接也就无法正常完成了。