on-call手册是故障时可直接执行的checklist,聚焦确认问题、临时止血、找人兜底三件事;每条指令须可复制粘贴、明确上下文、给出具体阈值和操作步骤。

on-call 手册不是文档,是故障时能直接抄起就用的 checklist
它不承载设计思想,也不解释原理——值班工程师凌晨三点被告警叫醒时,只关心三件事:怎么确认问题、怎么临时止血、找谁兜底。写成“Python 服务高可用设计规范”或“Django 架构演进史”,等于没写。
实操建议:
- 每条操作指令必须可复制粘贴:比如
curl -s http://localhost:8000/health | jq '.status',而不是“检查健康接口返回” - 所有命令默认假设在目标服务所在机器执行;若需跳转,明确写出
ssh app-prod-03,不写“登录对应实例” - 避免出现“视情况而定”“一般建议”——换成具体阈值:比如“若
redis-cli -h cache-prod info memory | grep used_memory_human输出超过12G,立即执行redis-cli -h cache-prod flushdb(并 Slack @infra)”
Python 进程挂了?先别 restart,看 systemctl status 和 journalctl
90% 的“服务起不来”其实卡在启动阶段,systemctl restart myapp 只会让失败更快重演。真正要盯的是进程为何没活过初始化。
常见错误现象:
立即学习“Python免费学习笔记(深入)”;
-
systemctl status myapp显示failed但没报错细节 - 手动跑
python manage.py runserver没问题,但用 systemd 启就退出
实操建议:
- 立刻查日志:
journalctl -u myapp -n 100 --no-pager(加--since "2 minutes ago"更准) - 重点看最后一行:是
ImportError?OperationalError: database is locked?还是Killed(OOM 被杀)? - 环境变量差异最常踩坑:systemd 默认不继承 shell 环境,
Environment=PYTHONPATH=/opt/myapp/src必须显式写进/etc/systemd/system/myapp.service
pip list 和 pip freeze 都不准,on-call 时该信哪个?
信 pip freeze,但前提是它来自当前运行环境。很多手册写“检查依赖版本”,结果让值班人去开发机上跑 pip freeze——那跟生产环境根本不是一回事。
这本书假定你没有任何关于脚本或一般程序的编程知识, 但是如果你具备相关的知识, 那么你将很容易就能够达到中高级的水平. . . 所有这些只是UNIX®浩瀚知识的一小部分. 你可以把本书作为教材, 自学手册, 或者是关于shell脚本技术的文档. 书中的练习和样例脚本中的注释将会与读者进行更好的互动, 但是最关键的前提是: 想真正学习脚本编程的唯一途径就是亲自动手编写脚本. 这本书也可作为教材来讲解一般的编程概念. 向伟大的中华民族的Linux用户致意! 我希望这本书能够帮助你们学习和理解L
使用场景:
- 怀疑是某次部署后出现兼容问题(比如
requests升级导致下游 API 调用失败) - 需要快速比对两台机器是否一致(如 prod-01 vs prod-02)
实操建议:
- 进入服务运行用户上下文再执行:
sudo -u www-data pip freeze > /tmp/prod-deps.txt - 不要用
pip list:它显示“最新可安装版本”,不是“当前已安装版本”;pip freeze才输出实际加载的包和精确版本 - 如果服务用
venv,务必激活后再跑:source /opt/myapp/venv/bin/activate && pip freeze
告警说 CPU 100%,但 top 里 Python 进程只占 30%?查 strace 和 GIL
Python 多线程服务在 CPU 告警时经常表现出“伪低负载”:top 看单个进程不高,但整体系统卡死。本质是 GIL + 阻塞系统调用混在一起,监控没抓到真凶。
性能影响:
- 纯计算型任务会被 GIL 锁死,
top显示高,但实际是单核满载 - 大量文件读写、DNS 查询、SSL 握手等系统调用会绕过 GIL,但阻塞线程,表现为
top低 +load average高 + 请求超时
实操建议:
- 先看全局负载:
uptime输出的load average若远高于 CPU 核数(如 16 核机器显示 40),大概率是 I/O 阻塞 - 抓可疑进程系统调用:
strace -p $(pgrep -f 'gunicorn.*wsgi') -e trace=open,connect,sendto,recvfrom -s 64 2>&1 | head -50 - 如果看到大量
connect(…) = -1 EINPROGRESS或长时间停在recvfrom(…),基本锁定是下游服务响应慢或 DNS 解析卡住
复杂点在于:Python 进程本身可能很“干净”,问题藏在它调用的 C 扩展、系统库、甚至内核参数里。on-call 手册里必须留一行:“若 strace 显示持续阻塞在某个 syscall,请直接 echo 'net.ipv4.tcp_fin_timeout = 30' >> /etc/sysctl.conf && sysctl -p 并通知 infra”。事情说清了就结束









