服务单元文件

systemd服务单元文件是一种Linux系统中的新型启动管理方式,它是一种基于配置文件的系统初始化和服务管理框架,取代了传统的 initd。在 systemd 中,每个服务都由一个单元文件(Unit)表示,单元文件存放在/usr/lib/systemd/system//etc/systemd/system/目录下,用于定义一个服务的启动、运行和停止方式等。

以前使用 sudo service mysql start 来启动服务,而现在使用 sudo systemctl start mysqld.service,将 service 替换成了 systemctl 来管理服务。

而在命令 sudo systemctl start mysqld.service 中的 mysqld.service 服务在 /etc/systemd/system 文件夹中管理,一个服务对应着文件夹中的一个 .service 后缀文件。

systemd 的单元文件非常灵活,可以实现自启动,开启自动重启,记录进程ID等等功能,为管理系统服务提供了更加完善的机制。下面是一个简单的 nginx 服务的单元文件示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 示例 /etc/systemd/system/nginx.service

[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /var/run/nginx.pid
TimeoutStopSec=5
KillMode=process
KillSignal=SIGQUIT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

上面这个单元文件包含了三个主要部分:[Unit][Service] 和[Install],分别定义了单元的元数据、服务的具体运行方式和安装方式。

  • [Unit] 区块定义了单元的元数据,包括服务的描述信息(Description)、依赖关系(After)、单元的来源(SourcePath)、任务配置(Job)等。
  • [Service] 区块定义了服务的具体运行方式,包括服务的类型(Type)、服务的启动和停止命令(ExecStart 和 ExecStop)、服务的重启命令(ExecReload)、服务执行前或结束后需要运行的命令(ExecStartPre 和ExecStopPost)等。
  • [Install] 区块定义了服务安装的方式,比如将服务添加到对应的目标(WantedBy)。

总之,systemd 的单元文件提供了更加细致和灵活的配置能力,使得管理和设置服务变得更加简单和方便。

服务单元文件的配置项

下面是一个服务单元文件中可以用的配置项:

配置项所属部分 配置项 配置项的定义以及用法 可选取值
[Unit] Description 指定单元的描述信息
[Unit] Documentation 指定单元的在线文档
[Unit] Requires/Requisite 指定单元所需要的依赖,用于确定单元之间的关联性
[Unit] Wants 指定单元可选的依赖
[Unit] Conflicts 指定单元所冲突的单元名称
[Unit] Before/After 指定单元启动时间的先后顺序
[Unit] ConditionPathExists 条件指定单元是否启动
[Unit] ConditionPathIsMountPoint 条件指定单元是否启动
[Unit] StartLimitInterval 控制两次重启中间的时间间隔
[Unit] StartLimitBurst 控制重启的最大尝试次数
[Service] Type 指定服务的类型:simple, forking, oneshot simple, forking, oneshot, dbus, notify, idle
[Service] ExecStart 启动服务的命令,可以设置多个
[Service] Restart 指定服务是否触发自动重启 no, on-success, on-failure, on-abnormal, on-abort, on-watchdog
[Service] RestartSec 触发自动重启后的等待时间
[Service] PIDFile 想要跟踪的进程ID文件路径
[Service] ExecReload 重启服务的命令,可以设置多个
[Service] TimeoutStartSec 指定服务启动超时时间
[Service] TimeoutStopSec 指定服务停止超时时间
[Service] KillSignal 指定杀死进程的信号
[Service] Environment 指定要设置的环境变量
[Service] ExecStartPre 在ExecStart命令前执行其他的命令
[Service] ExecStartPost 在ExecStart命令后执行其他的命令
[Service] ExecStopPost 在ExecStop命令后执行其他的命令
[Service] PrivateTmp 将服务的临时文件夹设为私有的 true, false
[Install] WantedBy 指定安装时服务要添加到哪个目标下

其中,[Unit][Service] 和 [Install] 均为配置项所属部分,每个配置项的可选取值在上表中已经列出,可以参考以上的定义和用法进一步了解各个配置项的功能和可选取值。

WantedBy 是 systemd 服务单元文件中 [Install] 部分的一个配置项,用于指定服务单元要加入的 systemd 目标单元。

具体来说,当使用 systemctl enable [unit] 命令为某个服务单元启用开机自启动时,systemd 会读取该服务单元中 [Install] 部分的 WantedBy 配置项,并将服务单元添加到指定的 systemd 目标单元中。这样系统在下次启动时,就会自动启动这个服务单元。

例如,如果我们以 SSH 服务为例,它的安装指令有如下内容:

1
2
[Install]
WantedBy=multi-user.target

这表示当使用 systemctl enable sshd 命令为 SSH 服务启用开机自启动时,systemd 将会把它添加到 multi-user.target 这个 systemd 目标单元中,代表multi-user.target 在 SSH 服务之前启动。

总之,WantedBy 的作用是让系统知道某个服务单元应该在当前 systemd 目标单元启动前启动。

创建服务文件

那我们需要做的就是在 /etc/systemd/system 中创建一个服务文件,那服务文件的格式是什么呢?如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=service
After=local-fs.target

[Service]
Type=forking
Restart=always
RestartSec=60
LimitNOFILE=65535
ExecStart=/home/yunzhou/ws/filebrowser/linux-amd64-filebrowser/start.sh
ExecReload=/home/yunzhou/ws/filebrowser/linux-amd64-filebrowser/start.sh
ExecStop=/home/yunzhou/ws/filebrowser/linux-amd64-filebrowser/stop.sh

[Install]
WantedBy=multi-user.target
Alias=filebrowser.service

在服务文件中分为 3 部分:

  • Unit 段: 启动顺序与依赖关系,如 After=network.target,就说明在 network.target 服务启动之后;

  • Service 段: 启动行为,如何启动,启动类型,看上面的配置就知道意义了;

  • Install 段: 定义如何安装这个配置文件,即怎样做到开机启动。

1
注意该服务文件的权限要有可执行权限。

启动服务

在创建服务文件之后就可以启动服务:

1
2
3
4
5
6
7
8
// 重新加载服务列表
sudo systemctl daemon-reload

// 启动服务
sudo systemctl start filebrowser.service

// 或者重启服务
sudo systemctl restart filebrowser.service

在启动之后可以查看启动报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo systemctl status filebrowser.service

// 命令输出
yunzhou@yunzhou-PC:/etc/systemd/system$ systemctl status filebrowser.service
● filebrowser.service - service
Loaded: loaded (/etc/systemd/system/filebrowser.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2022-10-09 17:05:15 HKT; 16h ago
Process: 1508094 ExecStart=/home/yunzhou/ws/filebrowser/linux-amd64-filebrowser/start.sh (code=exited, status=0/SUCCESS)
Main PID: 1508095 (filebrowser)
Tasks: 14 (limit: 19110)
Memory: 4.9M
CGroup: /system.slice/filebrowser.service
└─1508095 /home/yunzhou/ws/filebrowser/linux-amd64-filebrowser/filebrowser -c /home/yunzhou/ws/filebrowser/linux-amd64-filebrowser/config.json

当看到 Active 状态为 active(running) 时,就代表着该服务启动成功。如果启动失败的话,可以使用 systemctl status xxx 服务 的语法来查看报错信息。

服务开机自启

设置服务开机自启使用以下命令:

1
2
3
4
5
// 设置开机自启
sudo systemctl enable filebrowser.service

// 设置关闭开机自启
sudo systemctl disbale filebrowser.service