18.04 - 如何在 systemd 单元中创建 PID 文件?

18.04 - 如何在 systemd 单元中创建 PID 文件?

我正在尝试使用 systemd 正确设置我的 minecraft 服务器,以便它正确确定进程的主 PID。我有以下 systemd 服务单元:

[Unit]
Description=Minecraft Server
After=network.target

[Service]
User=minecraft
Group=minecraft

WorkingDirectory=/srv/minecraft

ProtectSystem=full
ProtectHome=true

Type=forking

ExecStartPre=/srv/minecraft/mc_server.sh setup
ExecStart=/srv/minecraft/mc_server.sh start

PIDFile=/srv/minecraft/mc.pid

ExecStop=/srv/minecraft/mc_server.sh stop


[Install]
WantedBy=multi-user.target

当我尝试启动该服务时,收到此错误消息(主要问题是“无法从文件解析 PID“ 部分):

minecraft.service - Minecraft Server
   Loaded: loaded (/etc/systemd/system/minecraft.service; enabled; vendor preset: enabled)
   Active: failed (Result: timeout) since Wed 2018-11-28 12:57:03 PST; 6min ago
  Process: 9611 ExecStart=/srv/minecraft/mc_server.sh start (code=exited, status=0/SUCCESS)
  Process: 9591 ExecStartPre=/srv/minecraft/mc_server.sh setup (code=exited, status=0/SUCCESS)
 Main PID: 5213 (code=exited, status=0/SUCCESS)

Nov 28 12:55:32 xxx mc_server.sh[9591]: No Session found.  Creating and configuring.
Nov 28 12:55:32 xxx systemd[1]: minecraft.service: Found left-over process 9607 (tmux: server) in control group while starting unit. Ignoring.
Nov 28 12:55:32 xxx  systemd[1]: This usually indicates unclean termination of a previous run, or service implementation deficiencies.
Nov 28 12:55:32 xxx  systemd[1]: minecraft.service: Found left-over process 9608 (bash) in control group while starting unit. Ignoring.
Nov 28 12:55:32 xxx  systemd[1]: This usually indicates unclean termination of a previous run, or service implementation deficiencies.
Nov 28 12:55:32 xxx  mc_server.sh[9611]: Minecraft server successfully started
Nov 28 12:55:32 xxx  systemd[1]: minecraft.service: Failed to parse PID from file /srv/minecraft/mc.pid: Invalid argument
Nov 28 12:57:02 xxx  systemd[1]: minecraft.service: Start operation timed out. Terminating.
Nov 28 12:57:03 xxx  systemd[1]: minecraft.service: Failed with result 'timeout'.
Nov 28 12:57:03 xxx  systemd[1]: Failed to start Minecraft Server.

我不确定这个错误是什么意思,也不知道该如何解决。如果我删除 PIDfile= 选项,它就可以正常工作,但会将 tmux 进程列为主 PID,因此不会在日志中记录来自 java 进程的输出。我还注意到它实际上并没有将 PID 写入 mc.pid。直接运行脚本时,它确实可以正确写入 PID。

以下是“mc_server.sh start”的内容,这是我启动服务器和创建 PID 文件的方式(请注意,tmux 会话是在“mc_server.sh setup”期间创建的):

/usr/bin/tmux send-keys -t minecraft '/usr/bin/java -server -Xmx2048M -Xms1024M -jar /srv/minecraft/minecraft_server.jar nogui' C-m && \
/usr/bin/pgrep -u minecraft -f minecraft_server.jar > /srv/minecraft/mc.pid

答案1

选项PID文件systemd 用于读取 PID,而不是创建。在文档

采用指向服务 PID 文件的路径。建议对 Type= 设置为 forking 的服务使用此选项。指定的路径通常指向 /run/ 下的文件。如果指定了相对路径,则以 /run/ 为前缀。服务管理器将在服务启动后从此文件读取服务主进程的 PID。服务管理器不会写入此处配置的文件,但如果文件仍然存在,它会在服务关闭后删除该文件。PID 文件不需要由特权用户拥有,但如果它由非特权用户拥有,则必须强制执行额外的安全限制:该文件不能是指向其他用户拥有的文件的符号链接(无论是直接还是间接),并且 PID 文件必须引用已属于该服务的进程。

请注意,在现代项目中应避免使用 PID 文件。尽可能使用 Type=notify 或 Type=simple,这样就不需要使用 PID 文件来确定服务的主进程,并避免不必要的分叉。

这里也有很好的答案https://stackoverflow.com/a/67724450/15915956

相关内容