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

Node.js服务捕获SIGTERM后仍意外退出的原因排查

Node.js SIGTERM监听器未主动exit但进程退出的原因及排查方案

进程自动退出的核心原因

  • 你的SIGTERM监听器是异步函数,但内部没有任何阻塞事件循环或等待异步任务完成的逻辑,执行完console.log('EXITING')后,事件循环中已无待处理的任务(比如HTTP连接、定时器、未完成的Promise等),Node.js会按照默认机制自动退出进程。
  • 虽然自定义SIGTERM监听器会覆盖Node.js默认的终止行为,但只要事件循环为空,进程依然会正常退出。

排查内部exit/信号监听器的方法

1. 查看已注册的所有相关监听器

在代码中添加以下代码,打印所有与退出、终止信号相关的监听器,确认是否有第三方库或其他代码注册了额外的处理逻辑:

// 打印所有SIGTERM监听器
console.log('SIGTERM listeners:', process.listeners('SIGTERM'));
// 打印所有exit监听器
console.log('EXIT listeners:', process.listeners('exit'));
// 检查SIGINT等其他终止信号的监听器
console.log('SIGINT listeners:', process.listeners('SIGINT'));

2. 拦截process.exit()调用

如果怀疑有代码主动调用process.exit(),可以临时重写该方法捕获调用栈:

const originalExit = process.exit;
process.exit = function(code) {
  console.error('process.exit() called with code:', code);
  console.error(new Error('Exit stack trace').stack);
  originalExit(code);
};

这样一旦有代码触发exit,就能直接看到调用来源的栈信息。

3. 检查事件循环活跃状态

可以用Node.js内部API(生产环境谨慎使用)查看SIGTERM触发后的事件循环状态,确认是否已无活跃任务:

process.on('SIGTERM', async () => {
  console.log('EXITING');
  // 打印当前活跃的句柄和请求
  console.log('Active handles:', process._getActiveHandles());
  console.log('Active requests:', process._getActiveRequests());
});

优雅停机的正确实现思路

要实现真正的优雅停机,需在SIGTERM监听器中完成以下步骤:

  • 停止接收新请求(如关闭HTTP服务器)
  • 等待所有正在处理的请求/异步任务完成
  • 关闭数据库、缓存等外部连接
  • 最后主动调用process.exit()

示例代码:

const http = require('http');
const server = http.createServer((req, res) => {
  // 模拟长耗时请求
  setTimeout(() => {
    res.end('Request processed');
  }, 5000);
});

server.listen(3000);

process.on('SIGTERM', async () => {
  console.log('Starting graceful shutdown...');
  
  // 停止接收新请求
  server.close(async (err) => {
    if (err) {
      console.error('Server close error:', err);
      process.exit(1);
    }
    
    // 关闭外部连接示例
    // await database.close();
    // await cacheClient.quit();
    
    console.log('Graceful shutdown completed');
    process.exit(0);
  });
  
  // 设置超时兜底,防止无限等待
  setTimeout(() => {
    console.error('Graceful shutdown timed out, forcing exit');
    process.exit(1);
  }, 30000);
});

内容的提问来源于stack exchange,提问作者Suraj Suthar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 23:40:26