运维救援:Systemd 深度实战
现代 Linux 发行版几乎全部采用 Systemd。掌握了它,你就拥有了生产环境下的“系统管家”。
1. 现代指挥官:systemctl 核心
| 操作 | 命令 | 说明 |
|---|---|---|
| 开机自启 | sudo systemctl enable --now <svc> | --now 同时实现 enable + start |
| 查看状态 | systemctl status <svc> | 排障首选,显示运行树和最后日志 |
| 刷新配置 | sudo systemctl daemon-reload | 修改 .service 文件后必须执行 |
| 用户级别 | systemctl --user status <svc> | 无需 root,管理个人用户的后台服务 |
| 依赖分析 | systemctl list-dependencies <svc> | 查看该服务启动前需要等待哪些服务 |
2. 工业级 Unit 编写进阶
编写一个“稳健”的服务文件,需要考虑故障重试、安全隔离和资源限制。
视图分类:
进阶 Service 模板
创建 /etc/systemd/system/app.service:
[Unit]
Description=Production API Service
After=network.target mysql.service
# 如果 mysql 没启动成功,本服务也不启动
Requires=mysql.service
[Service]
Type=simple
ExecStart=/usr/bin/node /home/susu/app.js
Restart=always
# 失败后每 5 秒尝试重启
RestartSec=5s
# --- 安全与限制 ---
User=susu
Group=susu
# 限制文件描述符数量 (解决 Too many open files)
LimitNOFILE=65535
# 私有 /tmp 目录,与系统隔离
PrivateTmp=true
# 设置只读路径,防止程序被黑后篡改核心配置
ReadOnlyPaths=/etc/myapp/config.yaml
[Install]
WantedBy=multi-user.target临时运行技巧
systemd-run: 想让一个耗时很久的脚本在后台运行且不受终端退出影响?
sudo systemd-run --unit=my-task /home/susu/long-script.sh你可以像管理普通服务一样用 systemctl stop my-task 来停止它。
3. 告别 Cron:Systemd Timer
相比老旧的 Cron,Systemd Timer 提供了:更精准的触发时间、更清晰的日志 (journalctl) 以及任务重试机制。
▶ 创建一个每天凌晨 3 点运行的任务
- 定义任务内容 (
my-task.service):[Service] ExecStart=/usr/bin/backup-script.sh - 定义触发时间 (
my-task.timer):[Timer] # 每天凌晨 3 点 OnCalendar=*-*-* 03:00:00 # 确保错过时间后(如关机)开机立即补跑 Persistent=true [Install] WantedBy=timers.target
4. 启动瓶颈分析
觉得电脑开机太慢?Systemd 自带了精准的“秒表”。
- 总耗时:
systemd-analyze - 各服务耗时排名:
systemd-analyze blame - 关键路径分析:
systemd-analyze critical-chain
5. 结业练习
任务 1 资源限制实验
尝试在一个 Service 中设置 MemoryLimit=10M,然后运行一个大内存占用的脚本,观察 Systemd 是如何通过 OOM 保护机制杀掉该服务的。
练习 2 定时器迁移
将你现有的一个 crontab 任务迁移到 systemd.timer,并通过 systemctl list-timers 查看下次运行时间。
练习 3 依赖树
运行 systemctl list-dependencies multi-user.target,看看为了让你进入正常的桌面环境,Linux 到底启动了多少层级的服务。
Tip
一个优秀的运维工程师,不仅会写代码,更要学会如何让代码在 Systemd 的保护下“健康”地作为守护进程(Daemon)长久运行。