Heroku上Node.js后台worker无法优雅关闭 始终返回退出码1
问题根因
你遇到的异常退出本质是yarn作为启动父进程的信号转发逻辑缺陷导致的:
Heroku给dyno进程组发送SIGTERM信号后,作为父进程的yarn会先收到信号,它会给子Node进程转发SIGTERM,但yarn本身不会等待子进程执行完关闭逻辑,会直接自行退出。父进程退出后,操作系统会给仍在运行的子Node进程发送SIGHUP信号,Node对SIGHUP的默认处理逻辑是直接退出,退出码为1,刚好匹配你日志里的现象:刚打印完关闭启动日志就异常退出,没等到1秒后的优雅退出逻辑执行。
本地测试正常是因为你本地触发SIGTERM时通常是直接发给Node进程,不会触发父进程退出带来的SIGHUP信号。
解决方案
- 方案1(最推荐):修改你的Procfile配置,不要通过yarn/npm启动进程,直接调用node执行入口脚本。比如把原Procfile中
test-worker: yarn test-worker改为test-worker: node lib/test-worker/src/index.js,这样Node进程作为dyno的首进程直接接收信号,不存在父进程提前退出的问题,你的原有关闭逻辑就可以正常执行。 - 方案2:如果必须保留yarn启动的方式,可以在你的Node代码中新增SIGHUP信号的监听,阻止默认退出行为即可:
process.on('SIGHUP', () => { // 忽略SIGHUP信号,避免父进程yarn退出时被系统终止 });
内容的提问来源于stack exchange,提问作者dominik
相关产品推荐
相关产品推荐

