我在 Linux 机器上运行 2 个 nodJS 服务器。 为了让它们即使在我关闭控制台时也能运行,我用屏幕启动它们。 这一切都很完美。只要我的 Linux-Server-provider 不做任何维护工作。然后我必须手动重启服务器。
我目前正在尝试加强我的 NodeJS-Servers 以防止在我的 Linux-Server-Provider 的服务器维护后出现故障。当 Linux 服务器再次备份时,节点服务器应该会自动重启。
根据互联网上的许多文章中的一些,我能够创建一个位于
/etc/systemd/system/
. 的 systemd 服务
当我运行时,我可以看到服务被正确启用并加载到 systemd
systemctl list-units --all | grep my1984.service
我开火时也能看到它的状态
sudo systemctl status my1984.service
.
这一切都很好。但现在有趣的部分来了。
此服务调用 shell 脚本。这样做只会执行包含的 echo 命令。所有其他命令都被忽略。它是在服务器重启后运行还是在我通过
sudo systemctl start my1984.service
手动启动此服务时运行都没有关系。但是,当我使用 bash ./my1984.sh
运行 shell 脚本本身时,脚本会正常运行,这意味着所有 echo 命令以及所有其他命令都按预期进行了处理。
我尝试将错误消息记录到错误文件中,但没有出现任何错误。似乎该服务只是忽略了所有其他命令,但 echo。我是否使用 root 或我的本地用户调用该服务并不重要,我在 sudoers.d 中授予了一些额外的权限,以便能够使用 systemctl。
以下是我的服务内容:
[Unit]
Description=My 1984 Service Test
[Service]
ExecStart=/bin/bash /home/my1984/scripts/my1984.sh
[Install]
WantedBy=multi-user.target
这是我的shell脚本的内容
#!/bin/bash
echo $(date -u) "executing my1984.sh." >> /home/my1984/scripts/scripts.log
screen -ls >> scripts.log
screen -S NODE-Server 1 -d -m node /home/my1984/node-server1/bin/www 2>> error.log
echo $(date -u) "starting screen node @ node-server1." >> /home/my1984/scripts/scripts.log
screen -S NODE-Server 2 -d -m node /home/my1984/node-server2/bin/www 2>> error.log
echo $(date -u) "starting screen node @ node-server2." >> /home/my1984/scripts/scripts.log
echo $(date -u) "my1984.sh has been executed." >> /home/my1984/scripts/scripts.log
正如我所说,我的本地用户 my1984 已获得一些 sudo 权限,以便能够结合 sudo 运行某些 systemctl 命令。
当我使用 bash 命令在本地调用脚本时,它工作正常并且
screen -ls
在其列表中显示节点服务器。但是当 my1984.service 调用脚本时,只有 echo 命令被处理并将输出传递到文件中。 screen -ls
显示无内容。在这种情况下,没有错误被写入 error.log。
这种奇怪行为的原因是什么?
这里有一些关于我的Linux Server等的技术资料
Linux
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
Screen
Screen version 4.06.02 (GNU) 23-Oct-17
Node
v17.9.1
如果可以避免,启动双分叉过程(bash 启动屏幕启动节点)是不好的做法。
最简单的解决方案是只创建两个服务,每个节点服务器一个。
我运行多个 discord 机器人和 nodejs 应用程序,我正在以完全相同的方式进行操作。
我知道,这不是您所问问题的解决方案,但它是您实际问题的解决方案:)
启动和停止服务器将使用 systemctl 完成,您可以使用 journalctl 观察两个进程的控制台输出