Linux systemd服务管理
- 2025-04-08 20:55:00
- 丁国栋
- 原创 44
通常我们会使用 nohup /path/to/exec & 执行可执行程序并且让它在退出终端时也能保持在后台运行。这种方式相比systemd来说比较简单,但要实现开机启动还需要额外的配置,而且缺乏很多高级的配置,例如定义启动的顺序等,不如直接使用systemd来管理它。
不管是执行1次还是每次开机启动systemd都能轻松实现。
一般来说要使用systemd管理一个简单的可执行程序需要这个可执行程序有下面的特性之一:
- 可执行程序执行后一直处于前台运行,除非接收到停止的进程信号否则不会退出;
- 可执行程序执行后,它处于后台运行,除非接收到停止的进程信号否则不会退出;
- 可执行程序执行后,它处于后台运行并且还派生(fork)出子进程;
systemd service unit的类型(Type)有以下几种:
Type=simple模式假设服务在ExecStart命令执行后立即启动完成。这是最常用的配置方式,特别适合直接运行可执行程序的情况。通过设置合理的TimeoutStartSec值,可以避免卡住问题。
Type=forking模式用于那些会创建子进程的应用程序。在这种模式下,必须正确配置PIDFile以便systemd能够跟踪主进程。如果PID文件配置错误或程序未能正确生成PID文件,就会导致启动卡住的问题。
通常在 /lib/systemd/system/ 目录会有各种各样的service文件可以参考,我们自定义了一个service文件后也可以软链接到这个目录下让systemd接管,还可以执行 sudo systemctl enable xxx.service
让服务自动启动。
以下列举几种常用的服务配置文件。
simple类型
[Unit] Description=zth service Documentation=https://www.zentao.net/book/zentaopms/1719.html After=network.target [Service] #Type=notify Type=simple WorkingDirectory=/opt/zth User=root Group=root ExecStart=/opt/zth/zth ExecStop=/bin/kill -SIGHUP $MAINPID ExecReload=/bin/kill -SIGHUP $MAINPID && /opt/zth/zth #Restart=on-failure Restart=always TimeoutStopSec=10 KillMode=process LimitNOFILE=1048576 [Install] WantedBy=multi-user.target
forking 类型
[Unit] Description=My Node.js Application Service After=network.target [Service] Type=forking User=nodejs ExecStart=/usr/local/bin/mynode Restart=always WorkingDirectory=/opt/node-app Environment="NODE_ENV=production" TimeoutStartSec=30 PIDFile=/run/mynode.pid [Install] WantedBy=multi-user.target
查找进程对应的systemd service 文件。
例如我们发现有一个进程是 systemd-journald 占用内存较高,为了释放这些内存我们期望通过重新启动它实现,已知它的全称是 /lib/systemd/systemd-journald,并且查看它的PID稍后用于核对。
我们可以使用 grep systemd-journald -rni /lib/systemd/system/ 或者 grep ExecStart=/lib/systemd/systemd-journald -rni /lib/systemd/system/ 找到是 /lib/systemd/system/systemd-journald.service 这个文件。
继续执行 systemctl status systemd-journald.service,查看 Main PID 与要找的PID一致。所以确定是这个服务无疑,可以重启它 systemctl restart systemd-journald.service。也可以使用 journalctl -xe -u systemd-journald.service 查看它的日志。
--