如何配置forever实现Node.js脚本按错误类型差异化重启?
实现Forever差异化重启:部分错误延迟30分钟,其余立即重启
这问题我之前帮朋友处理过,其实核心思路是通过退出码区分错误类型,再配合一个简单的包装脚本来实现差异化重启逻辑,具体分两步走:
1. 在Node.js脚本中给错误打"标记"——返回不同退出码
首先得在你的Node.js脚本里,把需要延迟重启的错误和普通错误区分开,然后用不同的退出码告诉外部脚本该怎么处理。
你可以通过监听uncaughtException和unhandledRejection事件来捕获所有未处理的错误,然后根据错误特征(比如错误消息、错误代码、自定义错误类型)来决定退出码:
// 捕获未处理的同步异常 process.on('uncaughtException', (err) => { console.error('[崩溃] 未捕获异常:', err); // 这里根据你的业务场景定义判断逻辑,比如匹配特定错误消息 const needDelayRestart = err.message.includes('第三方API限制') || err.code === 'ECONNRESET_FROM_RATE_LIMIT'; if (needDelayRestart) { process.exit(2); // 用退出码2标记"需要延迟重启"的错误 } else { process.exit(1); // 用退出码1标记"立即重启"的普通错误 } }); // 捕获未处理的Promise拒绝 process.on('unhandledRejection', (reason, promise) => { console.error('[崩溃] 未处理Promise拒绝:', reason); const needDelayRestart = reason?.message?.includes('数据库连接池耗尽'); process.exit(needDelayRestart ? 2 : 1); }); // 你的业务代码... // 比如如果是主动抛出的错误,也可以在catch块里指定退出码 try { // 业务逻辑 } catch (err) { if (err instanceof CustomNeedDelayError) { process.exit(2); } else { process.exit(1); } }
2. 写一个Shell包装脚本,根据退出码执行差异化重启
Forever本身没有直接根据错误类型设置重启延迟的功能,但我们可以写一个简单的Shell脚本作为"中间层",它负责运行Node.js脚本,然后根据退出码决定是立即重启还是等30分钟再重启。
创建一个名为run-script.sh的文件,内容如下:
#!/bin/bash # 定义你的Node.js脚本路径 SCRIPT_PATH="./your-node-script.js" while true; do # 运行脚本并记录退出码 node "$SCRIPT_PATH" EXIT_CODE=$? case $EXIT_CODE in 2) echo "[重启策略] 检测到需延迟重启的错误,将在30分钟后重启..." sleep 1800 # 30分钟 = 1800秒 ;; 1) echo "[重启策略] 普通错误,立即重启(加2秒延迟避免无限循环)..." sleep 2 ;; 0) echo "[重启策略] 脚本正常退出,停止重启循环" break ;; *) echo "[重启策略] 未知退出码($EXIT_CODE),默认立即重启..." sleep 2 ;; esac done
然后给脚本添加执行权限:
chmod +x run-script.sh
最后用Forever来运行这个Shell脚本就行:
forever start run-script.sh
这样一来,当脚本因为标记为退出码2的错误崩溃时,包装脚本会等待30分钟再重启;其他错误则会在短暂延迟后立即重启。
额外小提示
- 如果你不想写Shell脚本,也可以考虑用Forever的
--spinSleepTime参数,但它是针对"频繁崩溃"的全局延迟,没法针对特定错误类型,所以不如包装脚本灵活。 - 记得给需要延迟重启的错误加上明确的日志标记,方便后续排查问题。
内容的提问来源于stack exchange,提问作者teddy
相关产品推荐
相关产品推荐

