这是一个为期5天的详细Linux systemd学习计划。本计划从基础概念和日常操作入手,逐步深入到自定义服务、定时任务和性能分析,旨在让你系统性地掌握systemd的核心功能。
学习准备
- 环境: 一台安装了现代Linux发行版(如Ubuntu 18.04+, CentOS 7+, Debian 9+)的虚拟机或物理机。强烈建议使用虚拟机,因为一些操作(如更改默认target)可能会让你无法进入图形界面,在虚拟机中修复会更容易。
- 知识储备: 熟悉基本的Linux命令行操作(如
ls
,cd
,cat
,sudo
)和使用一个文本编辑器(如vim
,nano
)。 - 心态:
systemd
功能强大但逻辑严谨。多动手实践,多看状态,多查日志是学习的关键。
学习计划概览
- 前3天 (核心内容): 掌握
systemd
的日常使用、核心概念和自定义服务,足以应对80%的日常运维工作。 - 后2天 (进阶内容): 深入了解高级特性,如定时器、依赖关系和性能优化,让你成为更专业的
systemd
使用者。
Day 1: 基础概念与日常服务管理
学习目标:
- 理解
systemd
的作用和核心概念。 - 熟练掌握管理系统服务(启动、停止、重启、查看状态)的常用命令。
核心内容:
-
systemd 是什么?(理论部分)
- Init系统简介: 了解Linux系统的第一个进程(PID 1)的作用。
- 为什么是 systemd: 相比传统的 SysVinit 或 Upstart,
systemd
提供了更快的启动速度(并行启动)、更强的依赖管理、统一的日志系统等优势。 - 核心概念 - Unit (单元):
systemd
管理的一切资源都称为"单元"。- 了解最常见的单元类型:
service
: 系统服务(最重要)target
: 一组单元的集合,类似于"运行级别"socket
: 套接字timer
: 定时器path
: 路径
-
systemctl
- 你的总指挥棒 (实践部分)- 这是与
systemd
交互最核心的命令。 - 管理服务生命周期: (以
sshd
或nginx
服务为例)- 启动服务:
sudo systemctl start sshd.service
- 停止服务:
sudo systemctl stop sshd
(后缀.service
通常可以省略) - 重启服务:
sudo systemctl restart sshd
- 重新加载配置:
sudo systemctl reload sshd
(服务不中断,仅重新加载配置文件)
- 启动服务:
- 查看服务状态:
- 查看详细状态:
systemctl status sshd
(这是最常用、最重要的排错命令,能看到服务是否运行、PID、日志摘要等) - 检查服务是否正在运行:
systemctl is-active sshd
- 查看详细状态:
- 管理开机自启:
- 设置开机自启:
sudo systemctl enable sshd
- 禁止开机自启:
sudo systemctl disable sshd
- 检查是否开机自启:
systemctl is-enabled sshd
- 设置开机自启:
- 屏蔽服务 (Mask):
sudo systemctl mask sshd
(彻底禁用服务,任何方式都无法启动)sudo systemctl unmask sshd
(取消屏蔽)
- 这是与
动手实践:
- 选择一个你系统上已安装的服务,如
sshd
,crond
,nginx
或docker
。 - 对该服务完整地练习
start
,stop
,restart
,status
命令,每次操作后都用status
检查其状态变化。 - 练习
enable
和disable
,并通过is-enabled
命令验证。重启虚拟机,确认enable
的服务是否自启,disable
的服务是否未启动。 - 列出系统中所有正在运行的服务:
systemctl list-units --type=service --state=running
Day 2: Unit 文件与 Target 管理
学习目标:
- 理解
systemd
Unit 文件的结构和存放位置。 - 理解
target
的概念以及如何切换系统运行级别。
核心内容:
- 深入 Unit 文件 (理论与实践)
- Unit 文件的位置:
systemd
会按特定顺序查找 Unit 文件。/usr/lib/systemd/system/
: 软件包安装的默认 Unit 文件。不要直接修改这里的文件。/etc/systemd/system/
: 系统管理员配置和修改 Unit 文件的地方。这里的配置会覆盖上面目录的同名文件。
- Unit 文件结构: (以
sshd.service
为例)- 使用
systemctl cat sshd
查看其内容。 - 主要分为三个段:
[Unit]
: 通用元数据,如描述 (Description=
) 和依赖关系 (After=
,Wants=
)。[Service]
: 服务专属配置,如启动命令 (ExecStart=
)、重启策略 (Restart=
)、运行用户 (User=
)。[Install]
: 安装信息,定义在enable
时,该服务应被链接到哪个target
(WantedBy=
)。
- 使用
- Unit 文件的位置:
- Target - 运行模式的集合 (实践部分)
target
unit 用来组织和启动一组其他的 unit,是systemd
中对"运行级别"的实现。- 常用 Targets:
multi-user.target
: 多用户命令行模式(类似运行级别3)。graphical.target
: 图形界面模式(类似运行级别5)。rescue.target
: 救援模式。reboot.target
,poweroff.target
: 重启与关机。
- 管理 Target:
- 查看当前默认 target:
systemctl get-default
- 设置默认 target:
sudo systemctl set-default multi-user.target
(警告:在有图形界面的系统上执行此命令,下次重启将进入命令行模式!) - 切换到其他 target:
sudo systemctl isolate graphical.target
(在命令行模式下执行此命令可启动图形界面)
- 查看当前默认 target:
动手实践:
- 使用
systemctl cat
命令查看sshd.service
和crond.service
的 unit 文件内容,尝试理解每一行的含义。 - 在你的虚拟机中,执行
systemctl get-default
查看当前的默认 target。 - 执行
sudo systemctl set-default multi-user.target
。 - 执行
sudo reboot
重启虚拟机,观察系统是否直接进入了命令行界面。 - 在命令行界面登录后,执行
sudo systemctl set-default graphical.target
,再次重启,确认系统恢复到图形界面。
Day 3: 创建自定义 Service 与日志管理
学习目标:
- 能够为自己的应用程序或脚本编写一个简单的
systemd
service 文件。 - 掌握使用
journalctl
查看和过滤系统日志。
核心内容:
-
编写你的第一个 Service (核心实践)
- 场景: 我们有一个简单的脚本,希望它能像系统服务一样在后台运行,并由
systemd
管理。 - 步骤:
-
创建脚本: 在
/usr/local/bin
下创建一个简单的脚本my_script.sh
。bash#!/bin/bash while true; do echo "Hello from my_script! Logging at $(date)" sleep 10 done
给它执行权限:
sudo chmod +x /usr/local/bin/my_script.sh
-
创建 Unit 文件: 在
/etc/systemd/system/
目录下创建my_app.service
。ini[Unit] Description=My Simple Application Service After=network.target [Service] ExecStart=/usr/local/bin/my_script.sh Restart=always User=nobody Group=nobody [Install] WantedBy=multi-user.target
-
通知 systemd: 创建或修改 Unit 文件后,必须 运行此命令使其生效:
sudo systemctl daemon-reload
-
管理你的新服务: 现在你可以像管理其他服务一样管理它了!
sudo systemctl start my_app
systemctl status my_app
sudo systemctl enable my_app
sudo systemctl stop my_app
-
- 场景: 我们有一个简单的脚本,希望它能像系统服务一样在后台运行,并由
-
journalctl
-systemd
的日志管家 (实践部分)systemd
有自己的日志系统journald
,所有服务(包括自定义服务)的stdout
和stderr
都会被捕获到这里。- 常用命令:
- 查看所有日志(从旧到新):
journalctl
- 反向查看所有日志(从新到旧):
journalctl -r
- 实时跟踪日志:
journalctl -f
(类似tail -f
) - 查看特定服务的日志:
journalctl -u my_app.service
- 结合
-f
跟踪特定服务日志:journalctl -f -u my_app.service
- 按时间过滤:
- 查看今天的所有日志:
journalctl --since "today"
- 查看过去一小时的日志:
journalctl --since "1 hour ago"
- 查看今天的所有日志:
- 按优先级过滤(如错误):
journalctl -p err
- 查看所有日志(从旧到新):
动手实践:
- 完整地按照上述步骤,创建并运行你自己的
my_app.service
。 - 使用
systemctl status
检查服务是否正常运行。 - 使用
journalctl -u my_app.service
查看你的脚本输出的 "Hello..." 日志。 - 停止服务,修改脚本中的
echo
内容,然后重启服务,使用journalctl -f -u my_app
实时观察日志变化。 - 尝试查看
sshd
服务在过去一天的日志。
Day 4: 进阶 - 定时器与依赖管理
学习目标:
- 使用
systemd Timer
替代cron
创建定时任务。 - 理解 Unit 文件中
Wants
,Requires
,After
,Before
的含义。
核心内容:
-
Timer Units - 现代化的 Cron (实践部分)
systemd
timer 提供了比cron
更灵活和强大的定时任务功能。一个定时任务由两个文件组成:.timer
文件(定义何时运行)和.service
文件(定义运行什么)。- 步骤:
-
创建 Service 文件: 创建
/etc/systemd/system/my_backup.service
,定义要执行的任务。ini[Unit] Description=My Backup Service Logic [Service] Type=oneshot ExecStart=/bin/bash -c 'echo "Performing backup at $(date)" >> /tmp/backup.log'
注意
Type=oneshot
,表示这个服务执行完一个任务就退出。 -
创建 Timer 文件: 创建同名的
.timer
文件/etc/systemd/system/my_backup.timer
。ini[Unit] Description=Run my_backup.service every minute [Timer] OnBootSec=1min # 系统启动1分钟后执行一次 OnUnitActiveSec=1m # 服务上次执行成功后1分钟再次执行 # OnCalendar=*-*-* *:*:00 # 也可以用类似cron的日历格式 [Install] WantedBy=timers.target
-
激活和管理:
sudo systemctl daemon-reload
- 启动并自启 Timer:
sudo systemctl enable --now my_backup.timer
- 查看所有 timers 状态:
systemctl list-timers --all
-
-
依赖关系指令 (理论部分)
- 排序依赖:
After=
和Before=
After=network.target
: 表示本服务应该在network.target
启动之后才启动。Before=sshd.service
: 表示本服务应该在sshd.service
启动之前启动。- 这只规定了启动顺序,没有强制依赖。
- 需求依赖:
Wants=
和Requires=
Wants=redis.service
: 表示本服务希望redis.service
也一起启动。如果redis
启动失败,本服务不受影响。这是最常见的依赖。Requires=database.service
: 表示本服务强依赖 于database.service
。如果database
启动失败,systemd
将不会启动本服务。
- 排序依赖:
动手实践:
- 完整地创建
my_backup.service
和my_backup.timer
。 - 激活 timer 后,使用
systemctl list-timers
和tail -f /tmp/backup.log
来验证任务是否按时执行。 - 阅读你系统中
docker.service
或nginx.service
的 Unit 文件,分析它的After=
和Wants=
字段,理解它的启动依赖。
Day 5: 进阶 - 系统分析与用户服务
学习目标:
- 使用
systemd-analyze
分析系统启动性能。 - 了解如何以普通用户身份运行
systemd
服务。
核心内容:
-
系统性能分析 -
systemd-analyze
(实践部分)systemd
记录了详细的启动过程耗时,可以用systemd-analyze
工具进行分析。- 常用命令:
- 查看总启动耗时:
systemd-analyze
- 列出各服务启动耗时排行:
systemd-analyze blame
(非常有用,可以快速找到拖慢启动速度的服务) - 生成启动过程的 SVG 矢量图:
systemd-analyze plot > /tmp/boot_plot.svg
- 显示关键链 (critical chain):
systemd-analyze critical-chain
(显示哪些服务阻塞了后续服务的启动)
- 查看总启动耗时:
-
用户级别的 systemd 服务 (理论与实践)
systemd
不仅可以为系统(root)管理服务,也可以为每个登录用户管理服务。这对于运行一些用户级别的后台应用(如开发工具、同步客户端)非常有用。- 特点:
- Unit 文件放在
~/.config/systemd/user/
目录下。 - 使用
systemctl --user
命令进行管理(无需sudo
)。 - 服务会随用户登录而启动,随用户退出而停止。
- Unit 文件放在
- 实践:
- 在
~/.config/systemd/user/
目录下创建一个my_user_app.service
文件。 - 内容与系统服务类似,但
[Install]
部分通常是WantedBy=default.target
。 - 使用
systemctl --user daemon-reload
加载。 - 使用
systemctl --user start my_user_app
启动。 - 使用
systemctl --user status my_user_app
查看状态。
- 在
动手实践:
- 在你的系统上运行
systemd-analyze blame
,看看哪个服务是启动最慢的"拖油瓶"。 - 尝试将 Day 3 创建的
my_app.service
改造成一个用户服务,并放在用户目录下进行管理。注销再登录,看看服务是否自动启动。 - (选做)探索
systemd
的其他组件,如logind
(loginctl
命令)、resolved
(resolvectl
命令)。
总结: 通过这 5 天的学习,你将从一个 systemd
的初学者成长为一个熟练的使用者。关键在于将理论与实践相结合,不断地通过 status
和 journalctl
来观察和验证你的操作。