这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战
在使用 systemd
配置系统服务的时候,都是从一个 Unit 配置文件开始的,这篇文章从一个例子入手,来聊一聊怎样看一个服务的 Unit 配置文件。
我们从比较常用的 Nginx 的 Unit 配置文件入手,当在 Linux 系统中通过包管理器安装 Nginx 之后,会自动添加 Nginx 的系统服务配置,要查看 Nginx 的服务配置,可以使用如下的命令:
systemctl cat nginx.service
复制代码
得到的内容去掉注释后如下:
[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target
[Service]
Type=forking
PIDFile=/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 /run/n
TimeoutStopSec=5
KillMode=mixed
[Install]
WantedBy=multi-user.target
复制代码
我们分别按照 [Unit]、[Service]、[Install] 三个部分来看。
Unit
这部分配置的是 Unit 的一些描述信息、系统顺序和依赖关系等信息。
Description 的值是描述信息,以上 Nginx 的例子中,描述了 Nginx 是一个高性能的 Web 服务器和反向代理服务器。
After 部分指的是它的启动顺序,如果 network.target 需要启动,那么 Nginx 会在其启动后启动。如果需要指定它在谁之前启动,可以使用 Before 字段。
注意,这里的 After 和 Before 配置的只是启动顺序,并不是依赖关系。如果要声明依赖关系,需要用到另外两个字段,Nginx 的配置中没有,如果你安装了 Docker,可以查看 docker.service 配置信息,能够在 Unit 部分看到如下两行:
Wants=network-online.target
Requires=docker.socket
复制代码
这里的 Wants 和 Requires 都代表依赖关系。Wants 表示弱依赖,就是说,如果 network-online.target 启动失败或者运行停止,不会影响 docker.service 的继续启动。而 Requires 代表强依赖关系,如果 docker.socket 启动失败或者运行停止,那么 docker.service 也要终止运行。
Service
接下来看 Service 的部分,这部分主要配置了当前的服务是如何启动的。
Type 字段是指启动的类型,这里的 forking
是指 ExecStart
字段将以 fork()
方式启动,此时父进程将会退出,子进程将成为主进程。Type 字段的默认值是 simple
,指 ExecStart
字段启动的进程为主进程。
PIDFile 字段指该服务 PID 文件的路径,一般都在 /run/
路径下。
接下来的几个以 Exec 开头的字段,配置的都是服务启动相关的命令:
ExecReload
:重启时执行ExecStop
:停止时执行ExecStartPre
:启动之前执行ExecStartPost
:启动之后执行ExecStopPost
:停止之后执行
这里配置的内容可以是一个命令,也可以是一个脚本文件的命令。
TimeoutStopSec 指的是 ExecStop 执行停止的超市时间,如果超过的这个时长,则会被强制关闭,这里关闭的方式则是由 KillMode=mixed
配置的内容来决定的。
Install
这一部分只有一行配置:
WantedBy=multi-user.target
复制代码
表示当前服务所在的 Target。关于 Target 的介绍,可以参考上一篇文章(systemd
中的 Unit 和 Target 是什么?)。
因为 Target 也是一个 Unit,我们可以通过 systemctl cat multi-user.target
命令,查看 multi-user.target 的配置文件,内容去掉注释后如下:
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
复制代码
只包含 Unit 的部分,没有启动部分的内容,因为启动 Target 其实就是启动这个 Target 中所有的服务。