文章目录
说明:
本文根据观看B站零基础Linux入门50、零基础Linux入门51 教程视频整理
在Ubuntu16.04下测试通过
一、核心概念
学习 Systemd 的第一步,就是搞懂"单元"(unit)是什么。
简单说,单元就是 Systemd 的最小功能单位,是单个进程的描述。一个个小的单元互相调用和依赖,组成一个庞大的任务管理系统,这就是 Systemd 的基本思想。
由于 Systemd 要做的事情太多,导致单元有很多不同的种类,大概一共有12种。举例来说,Service 单元负责后台服务,Timer 单元负责定时器,Slice 单元负责资源的分配。
每个单元都有一个单元描述文件,它们分散在三个目录。
/etc/systemd/system:管理员建立的执行脚本,类似于/etc/rc.d/rcN.d/Sxx类的功能,优先运行
/run/systemd/system:系统执行过程中所产生的服务脚本,运行次之
/lib/systemd/system:每个服务最主要的启动脚本设置,类似于之前的/etc/init.d,最后运行
注:视频教程里该目录为 /usr/lib/systemd/system,但ubuntu里没有该目录,估计是Centos系统才有
二、配置文件
使用systemctl -t help
可查看可用的unit类型,常用的有service,target,timer这3个
timer可以实现crontab的功能,且定时更加准确
root@imx8mmqiyang:~# systemctl -t help
Available unit types:
service
socket
target
device
mount
automount
swap
timer
path
slice
scope
- Service:文件扩展名为.service,用于定义系统服务
- Target:文件扩展名为.target,用于模拟实现运行级别服务
- Device:文件扩展名为.device,定义内核识别的设备
- Mount:文件扩展名为.mount,定义文件系统挂载点
- Socket:文件扩展名为.socket,标识进程间通信用的socket文件,也可以在系统启动时,延迟启动服务,实现按需启动
- Snapshot:文件扩展名为.snapshot,管理系统快照
- Swap:文件扩展名为.swap,标识swap设备
- Automount:文件扩展名为.automount,文件系统的自动挂载点
- Path:文件扩展名为.path,定义文件系统中一个文件或目录使用,常用于当文件系统变化时,延迟激活服务,如:spool目录
三、service文件格式
在unit文件中,以#开头的行后面的内容被认为是注释
相关布尔值
- 开启:1、yes、on、true
- 关闭:0、no、off、false
时间单位默认是秒,毫秒(ms),分钟(m)等必须显示说明
Service unit文件,包含**[Unit]、[Service]、[Install]**三个部分
[Unit]:定义与Unit类型无关的通用选项,用于提供unit的描述信息,unit行为以及依赖关系等
[Service]:与特定类型相关的专用选项
[Install]:定于由“systemctl enable”以及“systemctl disable”命令在实现服务启动或禁用时用到的一些选项
3.1 [Unit]段常用选项
- Description:描述信息
- After:定于unit的启动次序,标识当前unit应该晚于哪些unit 启动,功能与Before相反
- Requires:依赖到其他unit,是强依赖,被依赖的unit无法激活时,当前的unit也无法激活
- Wants:依赖到其他的unit,若依赖
- Conflicts:定义unit间的冲突关系
3.2 [Service]段常用选项
-
EnvironmentFile:环境配置文件
-
PIDFile:值指定一个文件,保存当前服务启动起来的进程PID号
-
ExecStart:指明启动unit要运行命令或脚本的绝对路径
-
ExecStartPre:ExecStart前运行
-
ExecStartPost:ExecStart后运行
-
ExecStop:指明停止unit要运行的命令或脚本
-
Restart:当设定Restart=1时,则当次的daemon服务意外终止后,会再次启动次服务
-
Type:定义影响ExecStart及相关参数的功能的unit进程启动类型
-
simple:默认值,启动后常驻内存中
-
forking:启动后做为父进程延伸出其他子程序作为daemon的主要服务,父进程在启动后会终止
-
oneshot:与simple类似,但不会常驻内存中
-
dbus:与simple类似,但必须要取得一个D-BUS的名称后,才会继续运行,因此通常要设定BusName才行,和socket编程有关
-
notify:在启动完成后,会发送一个通知消息
-
idle:与simple类似,等其他工作都顺利执行完毕后才会执行,通常是开机最后才执行的服务
-
3.3 [Install]段常用选项
- Alias:别名,可使用systemctl command Alias.service
- RequiredBy:被哪些unit所依赖,强依赖
- WantedBy:被哪些unit所依赖,若依赖
- Also:安装本服务时,还要安装别的相关服务
注:新建或更改unit文件后,需要重新加载配置文件,需使用如下命令
systemctl daemon-reload
四、systemd管理服务
systemd服务所关联的命令:systemctl,其主要的管理命令包括
内容 | 具体命令 |
---|---|
查看服务内容 | systemctl cat name.service |
启动 | systemctl start name.service |
停止 | systemctl stopname.service |
重启 | systemctl restart name.service |
状态 | systemctl status name.service |
条件式重启 | systemctl try-restart name.service |
禁止自动或手动重启 | systemctl mask name.service |
取消禁止 | systemctl unmask name.service |
查看所有服务 | systemctl list-units --type service --all |
开机自动启动 | systemctl enable name.service |
禁止开机自启 | systemctl disable name.service |
查看所有服务开机自启状态 | systemctl list-unit-files --type service |
查看服务是否开机自启 | systemctl is-enabled name.service |
查看服务依赖关系 | systemctl list-dependencies name.service |
杀掉进程 | systemctl kill unitname |
关机 | systemctl halt systemctl poweroff |
重启 | systemctl reboot |
挂起 | systemctl suspend |
休眠 | systemctl hibernate |
使用systemctl list-units --type service --all
查看所有的服务状态,其内容对应如下
dev@dev:~$ systemctl list-units --type service --all
UNIT LOAD ACTIVE SUB DESCRIPTION
accounts-daemon.service loaded active running Accounts Service
acpid.service loaded active running ACPI event daemon
alsa-restore.service loaded inactive dead Save/Restore Sound
alsa-state.service loaded inactive dead Manage Sound Card
anacron.service loaded inactive dead Run anacron jobs
apparmor.service loaded active exited LSB: AppArmor init
apport.service loaded active exited LSB: automatic cra
apt-daily-upgrade.service loaded inactive dead Daily apt upgrade
apt-daily.service loaded inactive dead Daily apt download
● auditd.service not-found inactive dead auditd.service
auth-rpcgss-module.service loaded inactive dead Kernel Module sup
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD
bluetooth.service loaded active running Bluetooth service
brltty.service loaded inactive dead Braille Device Sup
● cloud-config.service not-found inactive dead cloud-config.servi
colord.service loaded active running Manage, Install an
● console-screen.service not-found inactive dead console-screen.ser
console-setup.service loaded active exited Set console font a
cron.service loaded active running Regular background
cups-browsed.service loaded active running Make remote CUPS p
cups.service loaded active running CUPS Scheduler
dbus.service loaded active running D-Bus System Messa
- loaded:unit配置文件已处理
- active(running):一次或多次持续处理的运行
- active(exited):成功完成一次性的配置
- active(waiting):运行中,等待一个事件
- inactive:未运行
- enabled:开机启动
- disabled:开机不启动
- static:开机不启动,但可被另一个启用的服务激活
五、实例编写
5.1编写测试用执行脚本
编写test.sh,将当前日期,每隔一秒输出到 /tmp/test.txt文件中
dev@dev:~$ cat test.sh
#!/bin/bash
while :
do
echo `date` >> /tmp/test.txt
sleep 1
done
5.2 编写测试用服务
编写文件名为 test.service的服务
[Unit]
Description=My First Service
[Service]
Type=simple
ExecStart=/bin/bash /home/dev/test.sh
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
5.3 测试服务
将test.service拷贝到 /lib/systemd/system目录下,更新守护服务并启动test.service
dev@dev:~$ systemctl daemon-reload
dev@dev:~$ systemctl start test.service
dev@dev:~$ systemctl status test.service
● test.service - My First Service
Loaded: loaded (/lib/systemd/system/test.service; disabled; vendor preset: enable
Active: active (running) since 四 2022-07-07 15:28:49 CST; 11s ago
Main PID: 3893 (bash)
CGroup: /system.slice/test.service
├─3893 /bin/bash /home/dev/test.sh
└─3915 sleep 1
7月 07 15:28:49 dev systemd[1]: Started My First Service.
dev@dev:~$
此时查看/tmp/test.txt文件,可看到每秒增加一个时间
六、timer文件格式
timer需要和service配合使用
常用选项
将[Service]改为[Timer]
Unit:真正要执行的任务,默认是同名的带有.service后缀的单元
Persistent:如果设置了该字段,即使定时器到时没有启动,也会自动执行相应的单元
WakeSystem:如果系统休眠,是否自动唤醒系统
单调定时器:以系统中某个事件的发生作为计时器开始计时的起点
OnActiveSec:定时器生效后,多少时间开始执行任务
OnBootSec:系统启动后,多少时间开始执行任务
OnStartupSec:Systemd 进程启动后,多少时间开始执行任务
OnUnitActiveSec:该单元上次执行后,等多少时间再次执行
OnUnitInactiveSec:定时器上次关闭后多少时间,再次执行
日历定时器:以日历作为计时器开始计时的起点
OnCalendar,类似于crontab命令,使用-作为日期分割符,:作为事件分隔符
示例:
Thu,Fri 2022-*-1,5 11:12:13 表示2022年任意月份的1日和5日,如果是周四或周五,则在11:12:13分执行
*-*- *😗:00* 表示每分钟
*-*- 00:00:00* 表示每天
*-01-07 00:00:00 表示每半年
*:0/15 表示每15分钟
12,13,14:20,10,30 表示12/13/14点的10/20/30分钟
[Unit] 需要执行的单元
6.1做一个定时器示例
6.1.1 编写time文件
编写一个名为test.timer的文件
dev@dev:~$ cat test.timer
[Unit]
Description=My First Timer
[Timer]
Unit=test.service
OnActiveSec=10
[Install]
WantedBy=multi-user.target
dev@dev:~$
6.1.2 测试服务
操作步骤
- 将test.timer,test.service文件放到/lib/systemd/system目录下
- 使用 systemctl daemon-reload更新守护列表
- 使用systemctl status test.timer查看test.timer状态,此时为inactive
- 使用systemctl status test.service查看test.service状态
- 使用systemctl start test.timer启动test.timer
- 使用systemctl status test.timer查看test.timer状态,此时为active
dev@dev:~$ systemctl daemon-reload
dev@dev:~$ systemctl status test.timer
● test.timer - My First Timer
Loaded: loaded (/lib/systemd/system/test.timer; disabled; vendor preset: enabled)
Active: inactive (dead)
7月 07 17:01:01 dev systemd[1]: Started My First Timer.
7月 07 17:04:53 dev systemd[1]: Stopped My First Timer.
dev@dev:~$ systemctl status test.service
● test.service - My First Service
Loaded: loaded (/lib/systemd/system/test.service; disabled; vendor preset: enable
Active: inactive (dead)
7月 07 15:28:49 dev systemd[1]: Started My First Service.
7月 07 15:33:53 dev systemd[1]: Stopping test.service...
7月 07 15:33:53 dev systemd[1]: Stopped test.service.
7月 07 17:01:12 dev systemd[1]: Started My First Service.
7月 07 17:04:57 dev systemd[1]: Stopping My First Service...
7月 07 17:04:57 dev systemd[1]: Stopped My First Service.
dev@dev:~$ systemctl start test.timer
dev@dev:~$ systemctl status test.timer
● test.timer - My First Timer
Loaded: loaded (/lib/systemd/system/test.timer; disabled; vendor preset: enabled)
Active: active (waiting) since 四 2022-07-07 17:05:37 CST; 3s ago
7月 07 17:05:37 dev systemd[1]: Started My First Timer.
dev@dev:~$
七、日志查看
如果发生问题,就需要查看日志。Systemd 的日志功能很强,提供统一的命令。
#查看整个日志
$ sudo journalctl
#查看 mytimer.timer 的日志
$ sudo journalctl -u mytimer.timer
#查看 mytimer.timer 和 mytimer.service 的日志
$ sudo journalctl -u mytimer
#从结尾开始查看最新日志
$ sudo journalctl -f
#从结尾开始查看 mytimer.timer 的日志
$ journalctl -f -u timer.timer