You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js进程优雅关闭:任务完成后终止的正确实现

Node.js进程优雅关闭:等待所有任务完成后终止

原代码的核心问题

你的Java式写法在Node.js里会直接卡死进程:Node.js是单线程事件循环模型,同步while循环加上阻塞式sleep会彻底霸占事件循环,导致其他异步任务(包括那些修改tasksCount的Promise)完全没有执行机会,最终tasksCount永远不会降到0,进程陷入无限等待。

生产环境验证的解决方案

1. 正确实现非阻塞的"sleep"

Node.js里不能用阻塞式睡眠,必须用Promise封装setTimeout,这样既可以暂停当前逻辑,又不会阻塞事件循环:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

2. 异步化的优雅关闭逻辑

用async/await配合上述sleep,实现非阻塞的定期检查:

// 全局/模块级别维护任务计数,确保任务开始时递增、结束时递减
let tasksCount = 0;

async function gracefulShutdown(signal) {
  console.log(`Received ${signal}, starting graceful shutdown...`);

  // 关键步骤:先停止接收新任务(根据你的业务场景调整)
  // 示例:如果是HTTP服务,关闭服务器不再接受新请求
  // server.close();
  // 示例:如果是消息队列消费者,停止拉取新消息
  // consumer.pause();

  const checkInterval = 1000; // 每秒检查一次
  const maxWaitTime = 30 * 1000; // 最多等待30秒,防止无限挂起
  const startTime = Date.now();

  while (tasksCount > 0) {
    // 超时强制退出
    if (Date.now() - startTime > maxWaitTime) {
      console.error('Max wait time reached. Forcing process shutdown.');
      process.exit(1);
    }

    console.log(`Waiting for ${tasksCount} remaining tasks to finish. Next check in ${checkInterval / 1000}s`);
    await sleep(checkInterval);
  }

  console.log('All tasks completed. Shutting down process.');
  process.exit(0);
}

// 监听常见终止信号
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));

3. 正确维护任务计数

必须确保每个任务的计数在**所有分支(包括异常)**都能正确递减,建议用try/finally包裹任务逻辑:

async function executeTask(task) {
  tasksCount++;
  try {
    // 执行任务核心逻辑
    await task.run();
  } catch (err) {
    console.error('Task failed:', err);
  } finally {
    // 无论成功失败,都要递减计数
    tasksCount--;
  }
}

关键注意事项

  • 必须停止接收新任务:如果不停止新任务流入,tasksCount可能永远无法降到0,导致进程无法退出。
  • 设置超时兜底:避免因某个任务卡死(比如外部服务超时未响应)导致进程无限挂起。
  • 异步优先:Node.js的核心是事件循环,所有阻塞逻辑都要转化为异步形式,才能保证其他任务正常执行。

内容的提问来源于stack exchange,提问作者Ihor M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:17:37