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

Node.js使用forever运行时如何捕获SIGINT/SIGKILL信号执行退出前清理

问题根因分析

  1. 信号监听不全面:默认情况下forever停止进程时发送的是SIGTERM信号,而非你仅监听的SIGINT;且SIGKILL是系统级强制终止信号,任何程序都无法捕获,监听该信号完全无效。
  2. 路径匹配错误:你使用相对路径写入状态文件,实际写入路径是forever进程的工作目录,而非Node.js脚本所在目录,容易出现找不到文件的误判,也可能存在权限不足写入失败的问题。
  3. forever参数使用误区:forever stop 后应传入forever管理的任务ID、脚本名或forever生成的pid文件路径,直接传系统级pid可能导致信号发送逻辑异常。

解决方案

第一步:修正Node.js代码逻辑

const WebsocketServer = require("websocket").server
const jsonfile = require("jsonfile")
const path = require("path")

// 覆盖所有可捕获的常规终止信号
const exitSignals = ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGQUIT']

exitSignals.forEach(signal => {
  process.on(signal, () => {
    console.log(`${signal} fired, writing last state`)
    try {
      // 用绝对路径写入,避免相对路径的目录偏差
      const statePath = path.join(__dirname, "./someLastState.json")
      jsonfile.writeFileSync(statePath, states)
      // 确保文件写入完成后显式退出进程
      process.exit(0)
    } catch (err) {
      // 错误会被forever记录到指定的错误日志eIoT1.log中
      console.error("Write state failed:", err)
      process.exit(1)
    }
  })
})

// 原有websocket服务逻辑保持不变
...

第二步:调整forever启停操作

  1. 先验证代码本身有效性:直接运行node IoT1.js,按Ctrl+C发送SIGINT,确认控制台有对应输出、脚本所在目录正常生成状态文件,排除代码逻辑问题。
  2. 启动forever任务时显式指定工作目录和默认kill信号:
# 先停掉所有原有相关任务,避免冲突
forever stopall
# 把/path/to/your/script替换为你IoT1.js所在的实际目录
forever start -p /path/to/your/script -l lIoT1.log -e eIoT1.log -c node --killSignal=SIGTERM IoT1.js
  1. 停止任务时使用forever管理的脚本名操作,不要传系统级pid:
forever stop IoT1.js

第三步:结果验证

停止任务后分别检查对应文件:

  • 查看lIoT1.log是否有信号触发的日志输出
  • 查看IoT1.js所在目录下是否生成了someLastState.json文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:57:02