systemd是现代Linux发行版中广泛使用的系统和服务管理器,它取代了传统的SysV init和Upstart,提供了并行启动、依赖管理、日志集中、按需启动等强大功能,在Linux系统中调用systemd,通常通过命令行工具、单元文件管理或编程接口实现,本文将详细介绍这些方法。
命令行工具:systemctl的核心使用
systemctl是与systemd交互的主要命令行工具,用于管理服务、挂载点、设备、套接字等系统资源,其基本语法为systemctl [OPTIONS] COMMAND [UNIT]
,以下是常用操作:
服务管理
- 启动服务:
systemctl start nginx.service
(启动nginx服务,.service
可省略) - 停止服务:
systemctl stop nginx
- 重启服务:
systemctl restart nginx
- 重载配置:
systemctl reload nginx
(服务需支持重载,如Nginx) - 查看服务状态:
systemctl status nginx
,显示Active(活跃)状态、进程ID、最近日志等关键信息
开机自启与禁用
- 设置开机自启:
systemctl enable nginx
(创建符号链接到/etc/systemd/system/
下的目标.target.wants/) - 禁用开机自启:
systemctl disable nginx
(删除上述符号链接) - 检查开机自启状态:
systemctl is-enabled nginx
,返回enabled
/disabled
/static
服务状态与日志
- 检查服务是否运行:
systemctl is-active nginx
,返回active
/inactive
/failed
- 查看服务依赖:
systemctl list-dependencies nginx
,显示服务依赖的其他单元(如target、service) - 查看服务日志:
journalctl -u nginx
,显示nginx服务的日志;journalctl -u nginx -f
实时跟踪日志
高级命令
- 屏蔽服务(禁止启动):
systemctl mask nginx
(创建指向/dev/null
的符号链接,即使手动启动也会失败) - 取消屏蔽:
systemctl unmask nginx
- 进入维护模式:
systemctl rescue
,通知所有非重要服务停止,仅保留核心服务 - 紧急模式:
systemctl emergency
,仅挂载根文件系统,用于系统修复
单元文件(Unit Files)管理
systemd通过单元文件定义和管理系统资源,单元文件是纯文本文件,通常以.service
、.mount
、.timer
等为后缀,存放在/usr/lib/systemd/system/
(系统默认)或/etc/systemd/system/
(管理员自定义)目录下。
单元文件类型
单元类型 | 扩展名 | 作用示例 |
---|---|---|
服务单元 | .service |
定义系统服务(如nginx、ssh) |
挂载单元 | .mount |
定义文件系统挂载点(如/mnt/data ) |
套接字单元 | .socket |
定义进程间通信套接字(如docker.socket ) |
定时器单元 | .timer |
定时触发任务(替代cron) |
目标单元 | .target |
定义系统运行目标(如multi-user.target 为多用户模式) |
服务单元文件结构
以自定义服务myapp.service
为例,文件内容如下:
[Unit] Description=My Custom Application After=network.target # 依赖网络服务启动 Requires=network.target # 强制依赖,网络失败则本服务不启动 [Service] Type=simple # 进程类型(simple/forking/oneshot等) ExecStart=/usr/bin/myapp --config /etc/myapp.conf # 启动命令 ExecStop=/bin/kill -TERM $MAINPID # 停止命令 Restart=always # 失败后自动重启(always/on-success/on-failure等) User=myuser # 运行用户 Group=mygroup # 运行组 Environment=NODE_ENV=production # 环境变量 [Install] WantedBy=multi-user.target # 安装到多用户目标,即开机自启
单元文件操作
- 创建单元文件:在
/etc/systemd/system/
下创建.service
文件,如vim /etc/systemd/system/myapp.service
- 重载systemd配置:
systemctl daemon-reload
(修改单元文件后必须执行,否则不生效) - 启用/启动服务:
systemctl enable --now myapp
(同时设置开机自启并启动) - 测试单元文件语法:
systemctl cat myapp.service | systemd-analyze verify -
高级功能与依赖管理
systemd的核心优势之一是强大的依赖管理,通过[Unit]
段落定义单元间的依赖关系,确保服务按正确顺序启动。
依赖关系关键词
After
:本单元在指定单元之后启动(不强制依赖,仅排序)Before
:本单元在指定单元之前启动Requires
:强制依赖,若指定单元失败,本单元无法启动Wants
:弱依赖,指定单元失败时不影响本单元启动Conflicts
:冲突关系,若指定单元运行,本单元无法启动(反之亦然)
目标(Target)管理
目标单元是一组单元的集合,用于定义系统运行级别。
default.target
:默认目标(通常指向graphical.target
或multi-user.target
)multi-user.target
:多用户命令行模式graphical.target
:图形界面模式poweroff.target
:关机目标
切换目标示例:systemctl isolate multi-user.target
(切换到命令行模式,不关机),systemctl reboot
(关机)。
定时器(Timer)替代cron
创建myapp.timer
单元文件实现定时任务:
[Unit] Description=Run Myapp Daily [Timer] OnCalendar=daily # 每天执行(可指定具体时间,如"09:00:00") Persistent=true # 若定时器未运行,补执行错过的任务 [Install] WantedBy=timers.target
启用定时器:systemctl enable --now myapp.timer
,查看定时器状态:systemctl list-timers --all
编程接口调用
除命令行外,还可通过D-Bus接口或编程语言调用systemd API,实现自动化管理。
D-Bus调用
systemd暴露D-Bus接口,可通过busctl
命令或编程语言(如Python、C)调用,通过D-Bus启动服务:
busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StartUnit 'ss' 'myapp.service' 'replace'
参数说明:'ss'
表示输入参数为两个字符串,'myapp.service'
为服务名,'replace'
为启动模式(replace/fail/replace-irreversibly)。
Python调用(systemd-python库)
安装库:pip install systemd
示例代码:
from systemd import journal, manager # 启动服务 manager = manager.Manager() manager.StartUnit('myapp.service', 'replace') # 查看服务状态 unit = manager.GetUnit('myapp.service') print(unit.ActiveState) # 输出: active/inactive/failed # 写入日志 j = journal.Journal() j.send('Myapp service started', PRIORITY=journal.INFO)
相关问答FAQs
Q1: systemctl status显示服务“Active: failed”,如何排查?
A: 可通过以下步骤排查:
- 查看详细日志:
journalctl -u myapp.service --no-pager -n 50
,检查错误信息(如端口占用、配置文件错误、权限不足); - 检查单元文件语法:
systemctl cat myapp.service | systemd-analyze verify -
; - 手动执行启动命令:
/usr/bin/myapp --config /etc/myapp.conf
,观察是否有错误输出; - 检查依赖服务:
systemctl list-dependencies myapp.service
,确保依赖的服务(如network.target)正常运行。
Q2: 如何让systemd在系统启动后延迟10秒再启动某个服务?
A: 可通过两种方式实现:
- 使用
After
和OnActiveSec
:在服务单元的[Unit]
段落添加After=network.target
,在[Service]
段落添加ExecStartPre=/bin/sleep 10
(启动前等待10秒); - 使用
timer
单元延迟启动:创建myapp-delay.service
和myapp-delay.timer
,在timer
单元中设置OnBootSec=10
(系统启动后10秒触发),# myapp-delay.timer [Timer] OnBootSec=10s [Install] WantedBy=timers.target
启用定时器:
systemctl enable --now myapp-delay.timer
,服务将通过定时器触发启动。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/33481.html