我有一台运行 CentOS 7 的远程服务器,只能通过 SSH 访问。我希望两个 java 服务器始终在其上运行,即使在 ISP 重新启动等之后也是如此。
所以我尝试制作一个 systemd 服务,在屏幕上启动两个 java 服务器。当我启动服务时,我没有收到任何错误消息,但它立即消失:(systemctl status -l blogpatcher.service)
* blogpatcher.service - Start blogpatcher servers
Loaded: loaded (/etc/systemd/system/blogpatcher.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Sat 2020-02-08 04:19:09 EST; 7s ago
Process: 22388 ExecStart=/usr/bin/bash /home/blogpatc/script/blogpatcher.sh (code=exited, status=0/SUCCESS)
Main PID: 22388 (code=exited, status=0/SUCCESS)
这是 blogpatcher.service 文件:
# vi /etc/systemd/system/blogpatcher.service
[Unit]
Description=Start blogpatcher servers
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/bash /home/blogpatc/script/blogpatcher.sh
TimeoutStartSec=90
[Install]
WantedBy=default.target
这是服务运行的脚本文件:
# vi /var/tmp/test_script.sh
#!/bin/bash
screen -dmS syn bash -c 'cd /home/blogpatc/server/;java -cp bloghelper_artifact_main.jar com.aperico.bloghelper.server.ThesaurusServer;exec bash'
如果我只是从 SSH 控制台运行脚本文件,它会按预期工作,并且由于没有错误消息,我有点困惑,想知道是否有人知道问题是什么?
答案1
在[Service]部分下添加:“RemainAfterExit=yes”将使屏幕保持打开状态。
答案2
问题大概出exec bash
在最后。没有bash
得到输入,因此它退出。如果您执行任何 shell 的 exec,都会执行相同的操作:没有留下任何输入,因此 shell 退出。
但更根本的是:为什么使用screen
?这里有什么好处呢?
只让 systemd 进行重启会有什么问题?
[Unit]
Description=Start blogpatcher server
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/bash /home/blogpatc/script/blogpatcher.sh
TimeoutStartSec=90
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
和
#!/bin/bash
cd /home/blogpatc/server/
java -cp bloghelper_artifact_main.jar com.aperico.bloghelper.server.ThesaurusServer
Systemd 有许多附加参数和可能性,您可能需要阅读它们。例如,如果该脚本仅用于设置工作目录(而不是像我假设的那样作为更复杂的启动脚本的开始),那么您可能需要查看WorkingDirectory
,正如 JdeBP 在注释中建议的那样。
如果您坚持screen
必须在启动脚本中使用它,那么单元文件的服务部分可能应该类似于:
[Service]
Type=simple
Restart=on-failure
WorkingDirectory=/home/blogpatc/server/
RestartSec=3
ExecStart=/usr/bin/screen -L -dm java -cp bloghelper_artifact_main.jar com.aperico.bloghelper.server.ThesaurusServer
或探索Type=forking
而不是Type=simple
.
答案3
您可以将exec
命令添加到 screen 前面,用 screen 进程替换 bash 进程。这允许systemctl
识别屏幕进程何时终止并使用其重新启动策略机制来重新启动它。这是修改后的脚本:
# vi /var/tmp/test_script.sh
#!/bin/bash
exec screen -dmS syn bash -c 'cd /home/blogpatc/server/;java -cp bloghelper_artifact_main.jar com.aperico.bloghelper.server.ThesaurusServer;exec bash'
这就是您指定重新启动策略的方式:
[Service]
# ...
Restart=always