第 7 章 · 服务管理与 systemd
「服务器常用服务怎么管理」的完整答案:启动/停止/重启/开机自启、查服务日志、手写服务配置、定时任务。Ubuntu 和 Rocky 都用 systemd,本章命令两系统完全通用,学一遍顶两遍。
本章目录
7.1 systemd 是什么 7.2 systemctl 全家桶 7.3 journalctl 日志 7.4 手写 unit 文件 7.5 开机自启原理 7.6 定时任务 7.7 服务排障五步 7.8 老命令兼容 自测题7.1systemd 是什么:进程 1 与「服务的操作系统」
- 开机后内核启动的第一个进程(PID 1)就是 systemd,它负责拉起并守护所有服务、管理日志、定时任务、网络、电源。
- 每个服务是一个 unit(单元),用配置文件描述:怎么启动、依赖谁、崩溃怎么处理。
- unit 文件位置:
/lib/systemd/system/(系统自带)、/etc/systemd/system/(管理员覆盖/自定义,优先级更高)。 - 查看 PID 1:
ps -p 1 -o comm=(应是 systemd)。
7.2systemctl 全家桶(背熟 = 服务管理通关)
sudo systemctl start nginx # 启动(本次生效)
sudo systemctl stop nginx # 停止
sudo systemctl restart nginx # 重启(改配置后常用)
sudo systemctl reload nginx # 热重载配置(不中断连接,Nginx 推荐)
sudo systemctl enable nginx # 开机自启(永久)
sudo systemctl disable nginx # 取消开机自启
sudo systemctl enable --now nginx # 自启 + 立即启动(二合一)
systemctl status nginx # 状态 + 最近日志 + 是否自启
systemctl is-active nginx # active/inactive(脚本判断用)
systemctl is-enabled nginx # enabled/disabled
systemctl list-units --type=service --state=running # 所有运行中的服务
systemctl list-unit-files | grep nginx # 服务文件与自启状态
sudo systemctl daemon-reload # 新增/修改 unit 后必须执行!
enable 与 start 的区别(新手必懂)
start = 现在启动;enable = 开机启动(创建软链接)。两者独立:可以「只启动不自启」(临时跑一下)或「自启但现在没跑」(下次开机才起来)。服务器上装完服务标准操作:enable --now。
7.3journalctl:服务日志统一入口
systemd 把服务输出统一收进 journal 日志(二进制,比散文件更好查):
journalctl -u nginx # 某服务全部日志
journalctl -u nginx -f # 实时跟踪(-f follow,排障最爱)
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx -p err # 只看错误级别(-p 级别过滤)
journalctl -b # 本次开机以来的日志(-b -1 上次开机)
journalctl --disk-usage # 日志占多少空间
journalctl --vacuum-time=7d # 清理 7 天前日志
sudo journalctl -xeu nginx # 故障经典组合:-x 附说明 -e 跳到末尾
传统文本日志仍在:/var/log/(syslog、nginx 自己的 access/error log),两者共存。规律:systemd 收服务启动错误,/var/log 收服务业务日志,排障时都看。
7.4手写 unit:把任意程序变成受管服务
你从 GitHub 下了一个程序,想让它开机自启、崩溃自动重启、日志统一管理 —— 写一个 unit 文件即可。示例(app 服务):
[Unit]
Description=My App Service # 描述
After=network.target postgresql.service # 在哪些目标/服务之后启动
Wants=network.target # 需要的目标(弱依赖)
[Service]
Type=simple # simple/forking/oneshot,见下
User=webapp # 以哪个用户运行(绝不跑 root!)
Group=webapp
WorkingDirectory=/opt/app
ExecStart=/opt/app/bin/app-server --config /etc/app.conf # 启动命令
Restart=on-failure # 崩溃自动重启(always/on-failure)
RestartSec=3 # 重启等待秒数
Environment=NODE_ENV=production # 环境变量
LimitNOFILE=65535 # 文件句柄上限(高并发应用)
[Install]
WantedBy=multi-user.target # 开机自启挂到多用户目标
sudo systemctl daemon-reload # 让 systemd 认识新文件(必做)
sudo systemctl enable --now app
systemctl status app
journalctl -u app -f # 看它是否正常跑起来
Type 三选一:simple(前台进程,最常见);forking(启动后 fork 到后台,用 PIDFile 指明);oneshot(执行一次就结束,适合初始化脚本)。判断:看程序是前台阻塞式运行(simple)还是自动 daemonize(forking)。
7.5开机自启原理(enable 干了什么)
systemctl enable app 的本质:在 /etc/systemd/system/multi-user.target.wants/ 下创建指向 unit 文件的软链接。删除该链接即 disable。你完全可以手动管理这个目录,但命令更稳。
7.6定时任务:cron / systemd timer / at 怎么选
| 工具 | 适用 | 示例 |
|---|---|---|
| cron | 日常周期任务(每天/每周/每月),最常用 | crontab -e 编辑:0 3 * * * /opt/backup.sh |
| systemd timer | 需要精确控制、依赖管理、错过补跑的周期任务 | 写 .timer 文件,更「systemd 化」,进阶用 |
| at | 一次性定时(几点几分跑一次) | echo "sh /opt/x.sh" | at 14:30 |
crontab -e # 编辑当前用户任务(首次选编辑器,推荐 nano)
crontab -l # 查看
crontab -r # 清空(慎用)
# 格式:分 时 日 月 周 命令
# 0 3 * * * 每天 3:00 执行备份
# */10 * * * * 每 10 分钟
# 0 2 * * 1 每周一 2:00
# 日志:grep CRON /var/log/syslog(Rocky: /var/log/cron)
cron 三条坑
① cron 环境变量极少(没有你 .bashrc 里的 PATH),命令写绝对路径或开头
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin;② 输出重定向到日志文件(>> /var/log/mytask.log 2>&1),否则静默失败找不到原因;③ 脚本先手动执行成功再挂 cron。
7.7服务排障五步(万能套路)
- 看状态:
systemctl status 服务—— active/failed、最近几行日志、主进程 PID。 - 看日志:
journalctl -u 服务 -n 50 --no-pager,找 error/denied/not found 关键词。 - 手动跑:
sudo 服务启动命令在前台执行,错误会直接打在屏幕(很多服务支持nginx -t之类测试命令先验配置)。 - 查权限与端口:配置文件权限、端口占用
ss -tlnp | grep 端口(第 8 章)。 - 改配置→daemon-reload→restart:改 unit 或配置文件后规范顺序:
daemon-reload(改 unit 时)→restart→ 再看status与日志确认。
「Failed to start」常见真凶
端口被占(换端口或停掉旧服务)、配置文件语法错(先跑
命令 -t 测试)、权限不足(User= 没有写日志目录权限)、依赖服务没起来(看 After= 与 systemctl status 依赖)、SELinux 拦截(Rocky,ausearch -m avc 查,第 9 章)。
7.8老命令兼容:service / chkconfig / /etc/init.d
老教程里的 service nginx start、chkconfig nginx on 在 systemd 时代只是兼容层(会转成 systemctl)。看到老命令别慌:service 服务 start 等价 systemctl start 服务。直接学 systemctl 即可,老命令认识就好。
本章自测题
- start 和 enable 的区别?装机后标准动作是什么?
- 改完 unit 文件后必须执行什么命令?
- 实时看 nginx 服务日志用什么?看错误级别日志呢?
- 写一个 app.service 的关键字段:以用户 webapp 运行、崩溃自动重启、开机自启,写出完整文件与启用命令。
- Type=simple 和 forking 分别适合什么程序?
- cron 格式「每天凌晨 3 点备份」「每 10 分钟检查」怎么写?cron 常见三个坑是什么?
- 服务 failed 后你的排查顺序是什么?
参考答案
1. start 现在启动;enable 开机自启(建软链接);标准动作 systemctl enable --now 服务。
2. systemctl daemon-reload。
3. journalctl -u nginx -f;journalctl -u nginx -p err。
4. [Service] 里 User=webapp、Restart=on-failure、ExecStart=/opt/app/bin/app;[Install] WantedBy=multi-user.target;然后 daemon-reload + enable --now。
5. simple 前台常驻程序;forking 自己转后台的守护型程序(配 PIDFile)。
6. 0 3 * * * /opt/backup.sh;*/10 * * * * /opt/check.sh。坑:环境变量少(用绝对路径)、输出要重定向留痕、先手动验证脚本。
7. status → journalctl 日志 → 前台手动跑/配置测试 → 查端口权限 → 修配置后 daemon-reload+restart。