Linux程序:Systemd
Systemd 是一系列工具的集合,其作用也远远不仅是启动操作系统,它还接管了后台服务,包括启动、停止、状态查询,以及日志归档、设备管理、电源管理、定时任务等许多职责,并支持通过特定事件(如插入特定 USB 设备)和特定端口数据触发的 On-demand(按需)任务。Systemd 的后台服务还有一个特殊的身份——它是系统中 PID 值为 1 的进程。
# 一、Unit 文件位置
按照 Systemd 约定,应该被放置指定的三个系统目录之一中。
/etc/systemd/system
:系统或用户自定义的配置文件。/run/systemd/system
:软件运行时生成的配置文件。/usr/lib/systemd/system
:系统或第三方软件安装时添加的配置文件。 (常用目录)
这三个目录是有优先级的,优先级123由高到低。因此,在三个目录中有同名文件的时候,只有优先级最高的目录里的那个文件会被使用。
# 二、Unit 文件说明
[Unit] : 启动顺序与依赖关系。
[Service] : 启动行为,如何启动,启动类型。
[Install] : 如何安装这个配置文件。
[Unit]
#描述信息
Description=
#定义应该在哪些服务之前启动。
Before=
#定义应该在哪些服务之后启动。
After=network.target remote-fs.target nss-lookup.target
#表示存在"弱依赖"关系,即如果依赖服务启动失败或停止运行,不影响继续执行。
Wants=
#表示存在"强依赖"关系,即如果依赖服务启动失败或异常退出,那么也必须退出。
Requires=
#注意,After和Before字段只涉及启动顺序,不涉及依赖关系。
#注意,Wants与Requires字段只涉及依赖关系,与启动顺序无关,默认情况下是同时启动的。
[Service]
#指定当前服务的环境参数文件。
EnvironmentFile=
#运行方式
Type=forking
#PID进程文件,可以防止启动多副本
PIDFile=
#开启服务前准备脚本,定义启动服务之前执行的命令
ExecStartPre=
#开启服务脚本,定义启动进程时执行的命令
ExecStart=
#开启服务后脚本,定义启动服务之后执行的命令
ExecStartPost=
#重启服务脚本,定义重启服务时执行的命令
ExecReload=
#停止服务脚本,定义停止服务时执行的命令
ExecStop=
#停止服务之后执行脚本,定义停止服务之后执行的命令
ExecStopPost=
#杀掉模式,定义Systemd如何停止服务
KillMode=
#定义了服务退出后,Systemd的重启方式
Restart=
#表示Systemd重启服务之前,需要等待的秒数。
RestartSec=
#独立空间
PrivateTmp=
#所有的启动设置之前,都可以加上一个连词号(-),表示"抑制错误",即发生错误的时候,不影响其他命令的执行。
#如EnvironmentFile=-/etc/sysconfig/sshd,即使/etc/sysconfig/sshd文件不存在,也不会抛出错误。
[Install]
#脚本启动模式,表示该服务所在的服务组,表示一组服务
WantedBy=multi-user.target
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Type字段 定义启动类型:
- simple(默认值):ExecStart字段启动的进程为主进程。
- forking:ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程。
- oneshot:类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务。
- dbus:类似于simple,但会等待 D-Bus 信号后启动。
- notify:类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务。
- idle:类似于simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合。
KillMode字段 定义Systemd如何停止服务:
- control-group(默认值):当前控制组里面的所有子进程,都会被杀掉。
- process:只杀主进程。
- mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号。
- none:没有进程会被杀掉,只是执行服务的 stop 命令。
Restart字段 定义了服务退出后,Systemd的重启方式:
对于守护进程,推荐设为on-failure。对于那些允许发生错误退出的服务,可以设为on-abnormal。
no(默认值):退出后不会重启
on-success:只有正常退出时(退出状态码为0),才会重启
on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启
on-abnormal:只有被信号终止和超时,才会重启
on-abort:只有在收到没有捕捉到的信号终止时,才会重启
on-watchdog:超时退出,才会重启
always:不管是什么退出原因,总是重启
WantedBy字段 定义该服务所在的 Target 服务组,表示一组服务。WantedBy=multi-user.target指的是服务所在的 Target 是multi-user.target。这个设置非常重要,因为执行systemctl enable 命令时, 服务就会放在/etc/systemd/system目录下面的multi-user.target.wants子目录之中。常用的 Target 有两个:一个是multi-user.target,表示多用户命令行状态;另一个是graphical.target,表示图形用户状态,它依赖于multi-user.target。官方 [Target 依赖关系图](https://www.freedesktop.org/software/systemd/man/bootup.html#System Manager Bootup)。
# 三、Systemd 常用命令
- 查看所有服务
systemctl list-unit-files --type service -all
服务状态:启用enabled、禁用disabled、屏蔽masked(在取消屏蔽之前处于非活动状态)、静态static、已生成generated。
- 开启服务
systemctl start 服务名
- 重起服务
systemctl restart 服务名
- 停止服务
systemctl stop 服务名
- 杀死服务的所有子进程
systemctl kill 服务名
- 查看服务当前的状态
systemctl status 服务名
输出:
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since 二 2022-05-10 07:27:18 CST; 7h ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 2782 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited,
status=0/SUCCESS)
Main PID: 1767 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
Tasks: 6
CGroup: /system.slice/httpd.service
├─1767 /usr/sbin/httpd -DFOREGROUND
├─2973 /usr/sbin/httpd -DFOREGROUND
├─2998 /usr/sbin/httpd -DFOREGROUND
├─3008 /usr/sbin/httpd -DFOREGROUND
├─3009 /usr/sbin/httpd -DFOREGROUND
└─3016 /usr/sbin/httpd -DFOREGROUND
5月 10 07:27:15 server.accother.com systemd[1]: Starting The Apache HTTP Server...
5月 10 07:27:18 server.accother.com systemd[1]: Started The Apache HTTP Server.
5月 10 08:40:01 server.accother.com systemd[1]: Reloading The Apache HTTP Server.
5月 10 08:40:01 server.accother.com systemd[1]: Reloaded The Apache HTTP Server.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
结果含义:
Loaded行:配置文件的位置,是否设为开机启动 Active行:表示正在运行 Main PID行:主进程ID Status行:由应用本身(这里是 httpd )提供的软件当前状态 CGroup块:应用的所有子进程 日志块:应用的日志
- 设置服务开机自启动
systemctl enable 服务名
- 设置服务不开机自启动
systemctl disable 服务名
- 重新加载服务的配置文件
systemctl reload 服务名
- 重载所有修改过的配置文件
systemctl daemon-reload
- 显示某个 Unit 的所有底层参数
systemctl show 服务名
- 显示某个 Unit 的指定属性的值
systemctl show -p 属性名 服务名
- 设置某个 Unit 的指定属性
systemctl set-property 服务名 属性名=属性值
- 查看默认的启动 Target(服务组)
systemctl get-default
# 四、更多参考
Linux Systemd服务 (opens new window)
Systemd 入门教程:命令篇 (opens new window)
Systemd 入门教程:实战篇 (opens new window)
下面是关于/etc/systemd/system/
、/lib/systemd/system/
(注意:在某些系统中可能不存在,常见的是/usr/lib/systemd/system/
)、/usr/lib/systemd/system/
、/run/systemd/system/
四个目录的作用和区别的总结表格:
目录 | 作用 | 优先级 | 备注 |
---|---|---|---|
/etc/systemd/system/ | 存放系统管理员自定义或修改的系统服务单元(unit)文件 | 最高 | 管理员可以通过在此目录下创建或修改单元文件来自定义系统服务。 |
/lib/systemd/system/ | (通常不存在,此处以/usr/lib/systemd/system/ 为准) | 中等(但注意,实际中可能不存在) | 存放由软件包安装的系统服务单元文件,由软件包维护者提供,不建议直接修改。 |
/usr/lib/systemd/system/ | 存放由软件包安装的系统服务单元文件 | 中等 | 与/lib/systemd/system/ 相似,但更为常见。同样不建议直接修改。 |
/run/systemd/system/ | 存放系统执行过程中动态生成的服务脚本或单元文件 | 较高(介于/etc/systemd/system/ 和/usr/lib/systemd/system/ 之间) | 这些文件是动态生成的,很少需要管理员直接修改。 |
备注说明:
- 优先级:systemd在加载单元文件时,会按照目录的优先级来读取文件。如果多个目录下存在同名单元文件,则优先级高的目录下的文件会覆盖优先级低的目录下的文件。
/lib/systemd/system/
目录:在某些Linux发行版中,这个目录可能不存在,或者其功能被/usr/lib/systemd/system/
目录所取代。因此,在实际应用中,应参考特定系统的布局和文档。- 自定义与系统管理:
/etc/systemd/system/
目录是系统管理员进行自定义服务管理的主要场所,而/usr/lib/systemd/system/
(或/lib/systemd/system/
,如果它存在的话)则主要用于存放由软件包提供的标准服务单元文件。 - 动态生成与静态文件:
/run/systemd/system/
目录下的文件是动态生成的,通常与系统的当前运行状态相关。这些文件不是由软件包安装或管理员手动创建的,而是由系统进程或服务在运行时根据需要生成的。
自定义service文件是应该放在:/etc/systemd/system还是:/usr/lib/systemd/system?
自定义service文件时,推荐将其放在**/etc/systemd/system**目录下。以下是关于这两个目录的详细解释:
- /usr/lib/systemd/system:此目录通常包含由软件包管理器安装的服务单元文件,即由系统或应用程序安装包提供的默认配置文件。这些文件一般是系统级的,不建议直接修改,以保持系统的稳定性和一致性。
- /etc/systemd/system:此目录用于存放系统管理员手动创建或修改的单元文件,包括自定义的服务。将自定义service文件放在这个目录下,可以确保它们与系统默认的服务文件分离,便于管理和维护。
此外,如果需要对现有的服务单元文件进行自定义修改,而不是完全创建一个新的文件,Red Hat等发行版建议采用以下方式:
- 在/etc/systemd/system/下创建一个与要修改的服务单元文件同名的目录,但要在目录名后加上“.d”扩展名。
- 在该目录下创建新的配置文件,这些文件将“累加其他设置”到原始的服务单元文件中。
这种方式允许在不直接修改原始服务单元文件的情况下,添加或覆盖特定的配置选项。
综上所述,对于自定义service文件,推荐将其放在/etc/systemd/system目录下,以遵循Linux系统的最佳实践,并确保系统的稳定性和可维护性。