supervisord 不会在停止命令时杀死所有生成的节点进程

supervisord not killing all spawned node processes on stop command

我在使用 supervisord 部署新服务时遇到了一些奇怪的事情。这些是相关部分:

# supervisord.conf

[program:express]
command=yarn re-express-start
# package.json
{
  "scripts": {
    "re-express-start": "node lib/js/client/Express.bs.js",
  }
}

当我运行supervisorctl start时,节点服务器如期启动。但是在我 运行 supervisorctl stop 之后,即使主管认为它已被杀死,服务器仍保持 运行ning。

如果我将 supervisord.conf 文件更改为直接执行 node lib/js/client/Express.bs.js(不经过 yarn),那么这会按预期工作。但我想通过 package.json 定义的脚本。

我查看了进程树的样子,但我不太明白为什么。以下是停止 supervisord 管理的服务前后的过程。

$ ps aux | grep node
user     12785  1.4  3.5 846404 72912 ?        Sl   16:30   0:00 node /usr/bin/yarn re-express-start
user     12796  0.0  0.0   4516   708 ?        S    16:30   0:00 /bin/sh -c node lib/js/client/Express.bs.js
user     12797  5.2  2.7 697648 56384 ?        Sl   16:30   0:00 /usr/bin/node lib/js/client/Express.bs.js
root     12830  0.0  0.0  14216  1004 pts/1    S+   16:30   0:00 grep --color=auto node

$ pstree -c -l -p -s 12785
systemd(1)───supervisord(7153)───node(12785)─┬─sh(12796)───node(12797)─┬─{node}(12798)
                                             │                         └─{node}(12807)
                                             ├─{node}(12786)
                                             └─{node}(12795)

$ supervisorctl stop express

$ ps aux | grep node
user     12797  0.7  2.7 697648 56384 ?        Sl   16:30   0:00 /usr/bin/node lib/js/client/Express.bs.js
root     12975  0.0  0.0  14216   980 pts/1    S+   16:32   0:00 grep --color=auto node

$ pstree -c -l -p -s 12797
systemd(1)───node(12797)─┬─{node}(12798)
                         └─{node}(12807)

$ kill 12797

$ ps aux | grep node
root     13426  0.0  0.0  14216   976 pts/1    S+   16:37   0:00 grep --color=auto node

从上面可以看出,执行服务器操作的“实际”工作负载进程具有 PID 12797。它由主管进程产生并嵌套在更多进程之下。 停止主管进程会停止 PID 为 1278512796 的进程,但 而不是 实际上重新附加到 init 进程的 12797

对这里发生的事情有什么想法吗?这是由于 某事 忽略了一些 SIGxxx 信号吗?我假设是 yarn 调用以某种方式吃掉了那些, 但我不知道如何以及如何重新配置​​。

我 运行 在 运行 节点 Express 应用程序时也遇到过这个问题。问题似乎是我正在让主管调用 npm start,它指的是 package.json start 脚本。该脚本只是调用 node app.js。解决方案似乎是直接从主管配置文件中调用该命令,如下所示:

[program:node]
...
command=node app.js
...
stopasgroup=true
stopsignal=QUIT

此外,我添加了 stopasgroup 并将 stopsignal 更改为退出。似乎需要停止信号才能正确终止进程。

我现在可以自由调用 supervisorctl restart node:node_00 而不会出现任何 ERROR (spawn error) 错误。