教程 rockylinux tutorial

systemd 服务管理

在 Rocky Linux 中,systemd 是默认的系统和服务管理器,负责启动系统、初始化服务和管理进程生命周期。本教程将详细介绍如何使用 systemd 来管理系统服务、创建自定义服务单元、设置定时任务等。

systemd 概述

systemd 是一个完整的系统和服务管理器,它替代了传统的 SysV init 系统。systemd 提供了以下核心功能:

  • 并行启动服务,加快系统引导速度
  • 基于依赖关系的服务启动顺序
  • 服务状态监控和自动恢复
  • 电源管理功能
  • 日志管理集成
  • 设备管理和挂载点管理

systemd 基本概念

单元(Units)

systemd 使用"单元"(Unit)来表示各种系统资源,最常见的单元类型包括:

  • service:系统服务
  • socket:套接字
  • device:设备文件
  • mount:挂载点
  • automount:自动挂载点
  • target:目标(类似于传统的运行级别)
  • timer:定时器(用于定时任务)
  • path:路径触发器
  • slice:进程组
  • scope:外部创建的进程组

目标(Targets)

Targets 类似于传统的运行级别,但更灵活。常见的 targets 包括:

  • poweroff.target:关机状态
  • rescue.target:单用户救援模式
  • multi-user.target:多用户文本模式
  • graphical.target:多用户图形界面模式
  • default.target:默认启动目标(通常链接到 multi-user.target 或 graphical.target)

服务管理基本命令

查看服务状态

bash
# 查看特定服务的状态
systemctl status service_name.service

# 查看所有服务的状态
systemctl list-units --type=service

# 查看所有已加载但未激活的服务
systemctl list-units --type=service --state=inactive

# 查看所有服务(包括未加载的)
systemctl list-unit-files --type=service

控制服务

bash
# 启动服务
systemctl start service_name.service

# 停止服务
systemctl stop service_name.service

# 重启服务
systemctl restart service_name.service

# 重新加载服务配置(不中断服务)
systemctl reload service_name.service

# 启动服务并使其在启动时自动运行
systemctl enable service_name.service

# 禁用服务的自动启动
systemctl disable service_name.service

# 检查服务是否已启用
systemctl is-enabled service_name.service

# 立即激活服务并在启动时启用
systemctl enable --now service_name.service

查看服务依赖关系

bash
# 查看服务的依赖项
systemctl list-dependencies service_name.service

# 查看哪些服务依赖于特定服务
systemctl list-dependencies --reverse service_name.service

系统控制命令

系统重启和关机

bash
# 重启系统
systemctl reboot

# 关机
systemctl poweroff

# 挂起系统
systemctl suspend

# 使系统进入休眠状态
systemctl hibernate

# 混合睡眠(同时休眠和挂起)
systemctl hybrid-sleep

切换目标(运行级别)

bash
# 查看当前目标
systemctl get-default

# 设置默认目标
systemctl set-default graphical.target

# 临时切换到另一个目标
systemctl isolate multi-user.target

服务日志管理

bash
# 查看服务日志
journalctl -u service_name.service

# 查看最近的服务日志
journalctl -u service_name.service -n 50

# 实时监控服务日志
journalctl -u service_name.service -f

# 查看特定时间范围的日志
journalctl -u service_name.service --since "2023-05-01" --until "2023-05-02"

# 查看启动日志
journalctl -b

# 查看上一次启动的日志
journalctl -b -1

服务单元文件

单元文件位置

systemd 单元文件存储在以下位置:

  • /usr/lib/systemd/system/:系统安装的单元文件
  • /etc/systemd/system/:用户或管理员创建的自定义单元文件
  • /run/systemd/system/:运行时生成的单元文件

单元文件结构

一个典型的服务单元文件包含以下部分:

ini
[Unit]
Description=服务描述
Documentation=文档URL
After=network.target sshd.service  # 依赖关系

[Service]
Type=服务类型(simple、forking、oneshot、dbus、notify、idle)
User=运行服务的用户
Group=运行服务的组
ExecStart=启动命令
ExecReload=重新加载命令
ExecStop=停止命令
Restart=何时重启服务(always、on-success、on-failure、on-abnormal、on-abort、on-watchdog)
RestartSec=重启前等待的秒数
TimeoutStartSec=启动超时时间
TimeoutStopSec=停止超时时间

[Install]
WantedBy=multi-user.target  # 此服务应该被哪些目标启用

创建自定义服务

示例:创建一个简单的服务

  1. 创建服务单元文件:
bash
sudo vim /etc/systemd/system/myapp.service

添加以下内容:

ini
[Unit]
Description=My Custom Application
After=network.target

[Service]
Type=simple
User=myuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 /opt/myapp/app.py
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
  1. 重新加载 systemd 配置:
bash
sudo systemctl daemon-reload
  1. 启动并启用服务:
bash
sudo systemctl enable --now myapp.service

不同类型的服务

simple 类型

最常见的服务类型,systemd 会启动 ExecStart 中指定的进程,并将其视为主要服务进程。

ini
[Service]
Type=simple
ExecStart=/usr/bin/application

forking 类型

当服务启动后会通过 fork 创建子进程并在后台运行,父进程则退出。

ini
[Service]
Type=forking
ExecStart=/usr/bin/application --daemon
PIDFile=/run/application.pid

oneshot 类型

适用于只需执行一次并退出的服务。

ini
[Service]
Type=oneshot
ExecStart=/usr/bin/script.sh
RemainAfterExit=yes

dbus 类型

服务启动后会获取一个特定的 D-Bus 名称。

ini
[Service]
Type=dbus
BusName=org.example.MyService
ExecStart=/usr/bin/myservice

notify 类型

服务启动后会通过 sd_notify() 函数发送通知。

ini
[Service]
Type=notify
ExecStart=/usr/bin/application
NotifyAccess=all

定时器(Timers)

systemd 定时器提供了比传统 cron 更强大的定时任务功能。

创建定时器

  1. 创建服务单元文件 /etc/systemd/system/backup.service:
ini
[Unit]
Description=Backup Service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
  1. 创建定时器单元文件 /etc/systemd/system/backup.timer:
ini
[Unit]
Description=Run backup daily

[Timer]
OnCalendar=*-*-* 02:00:00  # 每天凌晨 2 点运行
Persistent=true  # 系统启动时,如果错过了预定时间,立即执行一次

[Install]
WantedBy=timers.target
  1. 启用并启动定时器:
bash
sudo systemctl enable --now backup.timer

管理定时器

bash
# 查看定时器状态
systemctl list-timers

# 查看特定定时器状态
systemctl status backup.timer

# 手动触发定时器对应的服务
systemctl start backup.service

路径触发器(Paths)

路径触发器用于监控文件或目录的变化,并在变化发生时启动服务。

创建路径触发器

  1. 创建服务单元文件 /etc/systemd/system/process-file.service:
ini
[Unit]
Description=Process file when changed

[Service]
Type=oneshot
ExecStart=/usr/local/bin/process-file.sh
  1. 创建路径触发器单元文件 /etc/systemd/system/process-file.path:
ini
[Unit]
Description=Monitor file changes

[Path]
PathModified=/path/to/monitor/file.conf  # 监控文件修改
# 或监控目录:PathChanged=/path/to/monitor/

[Install]
WantedBy=multi-user.target
  1. 启用并启动路径触发器:
bash
sudo systemctl enable --now process-file.path

systemd 资源控制

控制进程资源限制

可以在服务单元文件中使用 Limit* 指令来控制服务的资源使用:

ini
[Service]
# 其他配置...
LimitCPU=10s  # 限制 CPU 使用时间
LimitNOFILE=1000  # 限制最大打开文件数
LimitNPROC=100  # 限制最大进程数
LimitAS=1G  # 限制地址空间(内存)

使用 cgroups 进行资源管理

可以使用 MemoryLimit、CPUQuota 等指令控制服务的资源使用:

ini
[Service]
# 其他配置...
MemoryLimit=500M  # 限制内存使用为 500MB
CPUQuota=50%  # 限制 CPU 使用为 50%

系统状态分析

系统启动时间分析

bash
# 查看系统启动时间
systemd-analyze

# 查看各个服务的启动时间
systemd-analyze blame

# 生成启动时间图表
systemd-analyze plot > bootplot.svg

系统日志分析

bash
# 查看系统日志概览
journalctl -p err..emerg  # 只查看错误和紧急日志
journalctl --since "1 hour ago"  # 查看过去一小时的日志
journalctl --disk-usage  # 查看日志占用的磁盘空间

systemd 常见问题与解决方案

服务无法启动

  • 问题:服务启动失败
  • 解决方案:
    • 检查服务状态获取详细错误信息:systemctl status service_name
    • 查看服务日志:journalctl -u service_name
    • 验证 ExecStart 路径是否正确
    • 检查服务依赖项是否已启动

服务无法自动启动

  • 问题:系统启动后服务未自动运行
  • 解决方案:
    • 确保服务已启用:systemctl enable service_name
    • 检查 WantedBy 设置是否正确
    • 检查依赖项是否满足

服务频繁重启

  • 问题:服务频繁重启
  • 解决方案:
    • 检查 Restart 和 RestartSec 设置
    • 查看服务日志找出崩溃原因
    • 考虑调整超时设置

最佳实践

  1. 使用标准路径:将自定义服务单元文件放在 /etc/systemd/system/
  2. 正确设置依赖关系:使用 After= 和 Requires= 指令
  3. 设置适当的用户权限:不要以 root 运行不需要 root 权限的服务
  4. 配置资源限制:使用 MemoryLimit、CPUQuota 等限制资源使用
  5. 设置重启策略:根据服务的性质选择合适的 Restart 选项
  6. 启用日志:确保服务输出被正确记录
  7. 定期检查:定期查看服务状态和日志,确保服务正常运行

总结

systemd 是 Rocky Linux 中强大的系统和服务管理器,通过本文介绍的命令和技术,您可以有效地管理系统服务、创建自定义服务、设置定时任务等。掌握 systemd 的使用对于系统管理员来说至关重要,它可以帮助您更好地控制和监控系统资源和服务。

systemd 的功能远不止本文所介绍的内容,随着您使用经验的积累,您将能够充分利用 systemd 的强大功能来优化系统管理。