警告
本文最后更新于 2023-01-30,文中内容可能已过时。
以下为资料来源,由本站收集重新整理发布,仅用于个人收藏,转载请直接标注以下来源连接
1. [Unit]
Unit
定义启动顺序与依赖关系
单元(Unit)是 Systemd
的最小功能单位,是单个进程的描述。一个个小的单元互相调用和依赖,组成一个庞大的任务管理系统
其他的单元类型
https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files
Systemd
根据他们描述的资源类型对单位进行分类。确定单元类型的最简单方法是使用其类型后缀,该后缀附加到资源名称的末尾。
以下列表描述了可用于以下各项的单位类型systemd
:
.service
: 服务单元描述如何管理服务器上的服务或应用程序。这将包括如何启动或停止服务,应在何种情况下自动启动服务,以及相关软件的依赖关系和订购信息。
.socket
: 套接字单元文件描述网络或IPC
套接字,或systemd
用于基于套接字的激活的FIFO缓冲区。这些.service
文件始终具有一个关联文件,该文件将在本单元定义的套接字上看到活动时启动。
.device
: 描述已被指定为需要systemd
管理的设备udev
或sysfs
文件系统的单元。并非所有设备都有.device
文件。.device
可能需要单元的一些场景是用于订购,安装和访问设备。
.mount
: 此单元定义要由其管理的系统上的挂载点systemd
。这些以安装路径命名,斜杠更改为破折号。其中的条目/etc/fstab
可以自动创建单位。
.automount
: 一个.automount
单元配置将自动挂载的挂载点。这些必须以它们引用的挂载点命名,并且必须具有匹配.mount
单元以定义挂载的细节。
.swap
: 此单元描述系统上的交换空间。这些单元的名称必须反映空间的设备或文件路径。
.target
: 目标单元用于在启动或更改状态时为其他单元提供同步点。它们还可用于使系统进入新状态。其他单位指定它们与目标的关系以与目标的操作联系起来。
.path
: 此单元定义可用于基于路径的激活的路径。默认情况下,.service
当路径达到指定状态时,将启动相同基本名称的单元。这用于inotify
监视更改的路径。
.timer
: .timer单元定义将由其管理的计时器systemd
,类似于cron
延迟或计划激活的作业。达到计时器时将启动匹配单元。
.snapshot
: 命令.snapshot
自动创建一个单元systemctl snapshot
。它允许您在进行更改后重建系统的当前状态。快照不会跨会话生存,并用于回滚临时状态。
.slice
: .slice
单元与Linux
控制组节点关联,允许限制资源或将资源分配给与该片关联的任何进程。该名称反映了它在cgroup
树中的层次结构位置。默认情况下,单位会根据其类型放置在某些切片中。
.scope
: 范围单元systemd
由从其总线接口接收的信息自动创建。这些用于管理外部创建的系统进程集。
1
2
3
4
5
6
|
Description=当前服务的描述
Documentation=给出文档的位置,一般就是服务启动命令的帮助文档
After=表示如果此字段标记的服务若需要启动,那么当前定义的服务需要在此标记服务器启动之后.
Before=表示如果此字段标记的服务若需要启动,那么当前定义的服务需要在此标记服务器启动之前.
Wants=表示此字段标记的服务与当前定义服务存在"弱依赖"关系,即表示当前定义的节点服务启动失败或者停止运行,不影响当前定义的服务继续执行.
Requires=表示此字段标记的服务与当前定义服务存在"强依赖"关系,即表示当前定义的节点服务启动失败或者停止运行,那么当前定义的服务也必须停止.
|
2. [Service]
Service
区块定义如何启动当前服务。
注意:[Service
]部分的启动、重启、停止命令全部要求使用绝对路径,使用相对路径则会报错!
1
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
|
Environment=指定当前服务运行的环境参数,该值使用key=value健值对
;Environment=LANG=C
EnvironmentFile=指定当前服务的环境参数文件。该文件内部的key=value键值对,可以用$key的形式,在当前配置文件中获取。
Type=字段定义服务启动类型
;Type=simple(默认值): ExecStart字段启动的进程为主进程
;Type=exec: 类似于simple,simple表示当fork()函数返回时,即表示启动完成,而exec则表示仅在fork()和execve()函数都执行成功时,才算启动完成.
;Type=forking:ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程
;Type=oneshot:类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务
;Type=dbus:类似于simple,但会等待 D-Bus 信号后启动
;Type=notify:类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务
;Type=idle:类似于simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合
TimeoutStopSec=停止服务时的等待的秒数,如果超过这个时间服务仍然没有停止,systemd 会使用 SIGKILL 信号强行杀死服务的进程。
TimeoutStartSec=启动服务时的等待的秒数,如果超过这个时间服务任然没有执行完所有的启动命令,则 systemd 会认为服务自动失败。
ExecStart=启动服务时执行的命令
ExecReload=重启服务时执行的命令
ExecStop=停止服务时执行的命令
ExecStartPre=启动服务之前执行的命令
ExecStartPost=启动服务之后执行的命令
ExecStopPost=停止服务之后执行的命令
User=指定运行服务的用户,会影响服务对本地文件系统的访问权限。
Group=指定运行服务的用户组,会影响服务对本地文件系统的访问权限。
RootDirectory=指定服务进程的根目录(默认: / ),如果配置了这个参数后,服务将无法访问指定目录以外的任何文件。
Nice=服务的进程优先级,值越小优先级越高,默认为0。-20为最高优先级,19为最低优先级
KillMode=表示systemd如何停止当前定义服务
;KillMode=control-group(默认值):当前控制组里面的所有子进程,都会被杀掉
;KillMode=process:只杀主进程
;KillMode=mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号
;KillMode=none:没有进程会被杀掉,只是执行服务的 stop 命令。
Restart=定义了当前定义服务退出后,Systemd的重启方式。
;Restart=no(默认值):退出后不会重启
;Restart=on-success:只有正常退出时(退出状态码为0),才会重启
;Restart=on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启
;Restart=on-abnormal:只有被信号终止和超时,才会重启
;Restart=on-abort:只有在收到没有捕捉到的信号终止时,才会重启
;Restart=on-watchdog:超时退出,才会重启
;Restart=always:不管是什么退出原因,总是重启
RestartSec=12s 表示 Systemd 重启服务之前,需要等待的秒数。
|
3. [Install]
Install
区块,定义如何安装这个配置文件,即怎样做到开机启动。
1
2
|
WantedBy=表示该服务所在的Target
; Target的含义是服务组,表示一组服务,一般来说,常用的 Target 有两个:一个是multi-user.target,表示多用户命令行状态;另一个是graphical.target,表示图形用户状态,它依赖于multi-user.target
|
4. systemd 的定时任务(.timer)
所谓定时任务,就是未来的某个或多个时点,预定要执行的任务,比如每五分钟收一次邮件、每天半夜两点分析一下日志等等。
Linux
系统通常都使用 cron
设置定时任务,但是 Systemd
也有这个功能,而且优点显著
- 自动生成日志,配合
Systemd
的日志工具,很方便除错
- 可以设置内存和
CPU
的使用额度,比如最多使用50%的 CPU
- 任务可以拆分,依赖其他
Systemd
单元,完成非常复杂的任务
每个单元都有一个单元描述文件,它们分散在三个目录。
/lib/systemd/system
:系统默认的单元文件
/etc/systemd/system
:用户安装的软件的单元文件
/usr/lib/systemd/system
:用户自己定义的单元文件
systemd
定时任务分为两个部分
- 任务执行部分
.service
- 用于定义如何执行该任务,无需配置如何安装(即定义
Install
)
- 定时执行部分
.timer
5. systemd 常用相关命令
5.1. systemctl 系统相关
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# 重启系统
$> sudo systemctl reboot
# 关闭系统,切断电源
$> sudo systemctl poweroff
# CPU停止工作
$> sudo systemctl halt
# 暂停系统
$> sudo systemctl suspend
# 让系统进入冬眠状态
$> sudo systemctl hibernate
# 让系统进入交互式休眠状态
$> sudo systemctl hybrid-sleep
# 启动进入救援状态(单用户状态)
$> sudo systemctl rescue
|
5.2. systemd-analyze命令用于查看启动耗时
1
2
3
4
5
6
7
8
9
10
11
|
# 查看启动耗时
$> systemd-analyze
# 查看每个服务的启动耗时
$> systemd-analyze blame
# 显示瀑布状的启动过程流
$> systemd-analyze critical-chain
# 显示指定服务的启动流
$> systemd-analyze critical-chain atd.service
|
5.3. loginctl命令用于查看当前登录的用户
1
2
3
4
5
6
7
8
|
# 列出当前session
$> loginctl list-sessions
# 列出当前登录用户
$> loginctl list-users
# 列出显示指定用户的信息
$> loginctl show-user ruanyf
|
5.4. systemctl 状态查询命令
1
2
3
4
5
6
7
8
|
# 显示某个 Unit 是否正在运行
$> systemctl is-active application.service
# 显示某个 Unit 是否处于启动失败状态
$> systemctl is-failed application.service
# 显示某个 Unit 服务是否建立了启动链接
$> systemctl is-enabled application.service
|
5.5. 系统日志管理
1
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# 查看所有日志(默认情况下 ,只保存本次启动的日志)
$> sudo journalctl
# 查看内核日志(不显示应用日志)
$> sudo journalctl -k
# 查看系统本次启动的日志
$> sudo journalctl -b
$> sudo journalctl -b -0
# 查看上一次启动的日志(需更改设置)
$> sudo journalctl -b -1
# 查看指定时间的日志
$> sudo journalctl --since="2012-10-30 18:17:16"
$> sudo journalctl --since "20 min ago"
$> sudo journalctl --since yesterday
$> sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"
$> sudo journalctl --since 09:00 --until "1 hour ago"
# 显示尾部的最新10行日志
$> sudo journalctl -n
# 显示尾部指定行数的日志
$> sudo journalctl -n 20
# 实时滚动显示最新日志
$> sudo journalctl -f
# 查看指定服务的日志
$> sudo journalctl /usr/lib/systemd/systemd
# 查看指定进程的日志
$> sudo journalctl _PID=1
# 查看某个路径的脚本的日志
$> sudo journalctl /usr/bin/bash
# 查看指定用户的日志
$> sudo journalctl _UID=33 --since today
# 查看某个 Unit 的日志
$> sudo journalctl -u nginx.service
$> sudo journalctl -u nginx.service --since today
# 实时滚动显示某个 Unit 的最新日志
$> sudo journalctl -u nginx.service -f
# 合并显示多个 Unit 的日志
$> journalctl -u nginx.service -u php-fpm.service --since today
# 查看指定优先级(及其以上级别)的日志,共有8级
# 0: emerg
# 1: alert
# 2: crit
# 3: err
# 4: warning
# 5: notice
# 6: info
# 7: debug
$> sudo journalctl -p err -b
# 日志默认分页输出,--no-pager 改为正常的标准输出
$> sudo journalctl --no-pager
# 以 JSON 格式(单行)输出
$> sudo journalctl -b -u nginx.service -o json
# 以 JSON 格式(多行)输出,可读性更好
$> sudo journalctl -b -u nginx.service -o json-pretty
# 显示日志占据的硬盘空间
$> sudo journalctl --disk-usage
# 指定日志文件占据的最大空间
$> sudo journalctl --vacuum-size=1G
# 指定日志文件保存多久
$> sudo journalctl --vacuum-time=1years
|
- 对于
[Timer]
节点, Systemd
提供以下一些字段。
OnActiveSec
:定时器生效后,多少时间开始执行任务
OnBootSec
:系统启动后,多少时间开始执行任务
OnStartupSec``:Systemd
进程启动后,多少时间开始执行任务
OnUnitActiveSec
:该单元上次执行后,等多少时间再次执行(s/h)
OnUnitInactiveSec
: 定时器上次关闭后多少时间,再次执行
OnCalendar
:基于绝对时间,而不是相对时间执行
AccuracySec
:如果因为各种原因,任务必须推迟执行,推迟的最大秒数,默认是60秒
Unit
:真正要执行的任务,默认是同名的带有.service
后缀的单元
Persistent
:如果设置了该字段,即使定时器到时没有启动,也会自动执行相应的单元
WakeSystem
:如果系统休眠,是否自动唤醒系统