3. Linux 基础 2:systemd、日志与服务治理
理解服务如何启动/重启/依赖与日志如何收集与查询。
你会获得
把“服务为什么起不来 / 为什么一会儿就挂”拆成可验证步骤的能力:systemd、日志、依赖、权限、资源。
核心心法
systemd 负责“让进程活”,日志负责“告诉你为什么”;治理负责“让它长期稳定地活”。
典型收益
上线后再也不靠“重启试试”:你能快速定位失败点,并把修复沉淀成护栏。
现实世界里,很多生产事故不是“代码写错了”,而是“服务管理与运行机制没做好”:进程起不来、配置找不到、权限不够、依赖没就绪、启动后立刻退出、日志写不出来。
这一章我们把 systemd 和日志当作你的“显微镜 + 外骨骼”:看得清,才能稳得住。
这一章我们把 systemd 和日志当作你的“显微镜 + 外骨骼”:看得清,才能稳得住。
1) systemd 是什么?你为什么需要它?
systemd 是 Linux 上最常见的服务管理系统。它做的事很朴素:
- 启动:按依赖关系把服务拉起来
- 守护:服务崩了自动重启,按策略退避
- 治理:限制资源、设置环境变量、定义运行用户
- 记录证据:日志统一进 journal(便于排障)
一句话对齐心智模型:你的应用只是一个进程;systemd 把它变成“可管理的服务”。
DevOps 的目标不是“能跑”,而是“能稳定地跑,并且出事时能快速恢复”。
DevOps 的目标不是“能跑”,而是“能稳定地跑,并且出事时能快速恢复”。
2) 单元(Unit)与依赖:服务不是孤岛
systemd 用 unit 来描述系统中的各种对象。你最常见的是:
.service:服务(你的应用).timer:定时任务(替代 cron 的常见方式).socket:socket 激活(按需启动服务).target:一组 unit 的集合(像“里程碑”)
图 1:systemd 启动链路(单位/依赖/重启策略)(动态)
把“起不来”变成“卡在哪个环节”:依赖没就绪?用户权限不对?ExecStart 失败?还是健康检查不过?
3) 写一个能上生产的 service:最小模板(解释每个关键点)
下面不是“唯一正确”,但它体现了生产服务最常见的关注点:运行身份、工作目录、环境变量、重启策略、以及日志证据链。
[Unit]
Description=MyApp service
After=network-online.target
Wants=network-online.target
[Service]
User=app
Group=app
WorkingDirectory=/opt/myapp
EnvironmentFile=/opt/myapp/.env
ExecStart=/opt/myapp/venv/bin/gunicorn --workers 2 --bind 127.0.0.1:8000 myapp.wsgi:application
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
为什么这几个字段特别重要:
- User/Group:权限与安全的边界(避免 root 运行)
- WorkingDirectory:避免相对路径坑(尤其是读配置/写文件)
- EnvironmentFile:把环境差异外置,便于审计与回滚
- Restart*:把“偶发崩溃”从事故变成可恢复事件(但要配合限速/告警)
- User/Group:权限与安全的边界(避免 root 运行)
- WorkingDirectory:避免相对路径坑(尤其是读配置/写文件)
- EnvironmentFile:把环境差异外置,便于审计与回滚
- Restart*:把“偶发崩溃”从事故变成可恢复事件(但要配合限速/告警)
4) 日志:从“看不见”到“证据链”
日志是排障的第一证据。但很多团队的日志体系像“散落的纸条”:找不到、看不懂、对不上一次发布。
在 systemd 体系里,你至少要掌握一套最常用的组合:
systemctl status myapp:服务状态 + 最近几行日志(第一眼)journalctl -u myapp -e:跳到最新日志(第二眼)journalctl -u myapp -S \"10 min ago\":按时间范围过滤(第三眼)journalctl -u myapp -f:实时跟随(像 tail -f)
图 2:日志的“流向”与“落点”(动态)
应用输出 → journal →(可选)收集与聚合 → 检索与告警。你要确保每一步都不丢证据。
5) 服务治理:让它“长期稳定地活”
当你能启动服务后,下一步是治理:避免它把机器拖垮,也避免它悄悄“半死不活”。
- 重启策略:崩了重启,但要有退避与告警(否则变成“无限重启掩盖问题”)。
- 资源限制:CPU/内存/文件句柄;防止某个服务把整台机器吃光。
- 健康检查:不只是端口通;要能反映依赖是否正常、线程池是否耗尽等。
- 发布与日志关联:每次发布要能在日志里看到版本号、提交号、配置版本。
一个很实用的规则:“自动重启”解决的是偶发性问题;“持续重启”通常意味着逻辑错误、配置错误、权限错误或依赖不可用。遇到持续重启,要回到证据链(journal)定位第一处失败。
6) 服务起不来怎么办?一条最短诊断路线(动态)
图 3:systemd 排障最短路径(动态)
不猜、不慌:从 status 到 journal,再回到 unit 配置与运行身份,最后定位到“具体哪条命令失败”。
本章小结:从“会管理”到“会治理”
- systemd 解决“服务生命周期管理”:依赖、启动、重启、资源与身份。
- journalctl 解决“证据链”:用时间范围与 unit 过滤,定位第一处失败。
- 治理思维:把修复沉淀为护栏(更好的 unit、合理的重启策略、日志与告警、发布可追溯)。