本文是一篇 systemd 服务配置的实践笔记,记录如何用 .service 文件把一个普通程序托管为 Linux 系统服务,并实现开机自动启动。内容基于服务器上的真实配置,适合刚接触 systemd 的嵌入式与后端开发者快速上手。
一、.service 配置文件在哪里
每一个 Linux 服务都由它对应的配置文件管理,这个文件位于 /etc/systemd/system/ 与 /usr/lib/systemd/system 目录下(两者差异本文暂不展开)。文件名以 .service 为后缀,例如 server.service。
二、配置文件结构与固定写法
一个典型的 .service 文件由三段组成:
[Unit]
Description=服务描述
After=服务依赖(在这些服务后启动本服务)
[Service]
Type=服务类型
ExecStart=启动命令
ExecStop=终止命令
ExecReload=重启命令
[Install]
WantedBy=服务安装设置
一般来说有些值是固定的,没有特殊需要我们直接套用即可。例如:
[Unit]
After 的值一般是:network.target remote-fs.target nss-lookup.target。
[Install]
WantedBy 一般是 multi-user.target。
[Service]
主要需要关注的内容在 [Service] 段。其中有一堆 Restart 参数,先不用深究。
Type 的值有以下几个:
- simple:默认类型。指定 ExecStart 后,simple 即为默认 Type,除非显式指定。simple 使用 ExecStart 创建的进程作为服务主进程,systemd 会立即启动服务。
- forking:ExecStart 脚本启动后会调用 fork() 创建子进程作为启动的一部分;初始化完成后父进程退出,子进程继续作为主进程执行。
- oneshot:类似 simple,但进程在 systemd 启动前就会退出,属一次性行为;可配合 RemainAfterExit=yes,让 systemd 认为进程退出后仍处于激活状态。
- dbus:与 simple 相似,期待或设置一个 name,通过 BusName= 指定。
- notify:与 simple 相似,守护进程启动时会发送推送消息通知 systemd。
常用的就是 simple 和 forking:一般前台运行的应用程序用 simple,后台 / 守护进程用 forking。
启动 / 停止 / 重启命令里调用的程序,必须全部使用绝对路径。
三、启动、停止与重启服务
配置写好后即可使用。先让系统重新读取所有服务文件:
systemctl daemon-reload
然后通过以下命令操控服务:
service server start # 启动服务
service server stop # 终止服务
service server restart # 重启服务
执行启动命令时,会运行配置文件中 ExecStart 的值;停止、重启分别对应 ExecStop、ExecReload 的值。
四、启用 / 禁用开机自启动
通过以下命令启用 / 禁用开机自启:
systemctl enable server # 启用开机自启
systemctl disable server # 禁用开机自启
五、实战示例:tcp_relay 服务
这是我在服务器上配置 tcp_relay 的一个示例:
[Unit]
Description=TCP relay
ConditionFileIsExecutable=/root/tcp_relay/relay
After=network-online.target
Wants=network-online.target
[Service]
StandardOutput=journal+console
StandardError=journal+console
StartLimitInterval=3600
StartLimitBurst=10
Type=simple
ExecStart=/root/tcp_relay/relay
ExecStop=killall -9 relay
ExecReload=killall -9 relay; /root/tcp_relay/relay
; on-failure always
#Restart=always
#RestartSec=5
#KillMode=process
[Install]
WantedBy=multi-user.target
六、查看服务日志
查看该服务的日志:
journalctl -u server.service
设置开机自启动:
sudo systemctl enable server.service
