本文目录导读:

制定一份Python应用的应急预案,核心在于将通用的运维/故障处理流程,与Python生态特有的技术栈(如依赖管理、框架、解释器特性)相结合。
以下是一份针对Python应用的应急预案模板及关键注意事项,你可以根据业务规模(如单机脚本、Web服务、数据处理Pipeline)进行调整。
预则立:风险评估与分级
在制定预案前,先明确你的应用可能出什么问题,Python项目常见故障点:
- 依赖/环境问题:
requirements.txt冲突、第三方库版本不兼容、pip install失败、虚拟环境损坏。 - 内存与性能问题:内存泄漏(常见于Pandas、Flask/Django应用)、全局解释器锁(GIL)导致的CPU瓶颈。
- 代码逻辑错误:未处理的异常、类型错误、异步任务死锁、数据竞争。
- 外部依赖故障:数据库断连、Redis超时、第三方API限流。
- 部署与配置:
.env文件缺失、路径硬编码、Python版本不一致(如3.8 vs 3.11)。
故障分级建议:
| 级别 | 描述 | 影响 | 响应时间 |
|---|---|---|---|
| P0 | 服务完全不可用 | 核心业务中断 | < 15分钟 |
| P1 | 主要功能受损 | 大量用户受影响,但可降级 | < 1小时 |
| P2 | 部分非关键功能异常 | 少数用户报错 | < 24小时 |
| P3 | 告警或微小隐患 | 无直接用户影响 | 迭代修复 |
核心应急预案模板
为了清晰,将预案拆解为通用流程和Python专项流程。
发现与告警(Detection & Alerting)
- 标准动作:监控系统(如Prometheus + Grafana)或用户报障触发工单。
- Python专项检查:
- 日志错乱?检查日志分割(
logging模块的RotatingFileHandler)是否因硬盘满而停止。 - 进程异常?检查
ps aux中的Python进程是D状态(不可中断)还是Z状态(僵尸)。 - 慢请求?如果是Web应用,记录慢请求(如Django的
django-silk或Flask的flask-profiler)。
- 日志错乱?检查日志分割(
初步响应(Immediate Response) - “止血”
停机时间不是用来修代码的,而是用来恢复服务的。
- 回滚(最优先)
- 操作:立即执行版本回滚(Git tag回滚 + 重新部署旧版本镜像/代码包)。
- Python注意:回滚后必须执行
pip install -r requirements.txt,确认依赖版本与旧代码匹配,否则可能出现ImportError。 - 时间:通常5-10分钟。
- 摘流量 / 降级
- 操作:从负载均衡摘掉实例;或通过配置中心(如Consul)关闭非核心功能。
- Python注意:如果应用使用了
celery(异步任务队列),应暂停新task的消费(celery control命令)或清空积压队列。
根因定位(Root Cause Analysis) - Python专项排查
如果无法直接回滚,或需要并行排查,按以下顺序检查:
-
检查OS资源
top/htop:查看Python进程的CPU和内存占用。free -h:是否有Swap使用(Python内存泄漏的常见信号)。df -h:日志或临时文件是否占满磁盘(Python日志库若未配置按大小或时间切割,会填满磁盘)。
-
生成并分析Python线程/内存快照
- 进程卡死/CPU高:
# 获取所有线程的堆栈,非常关键! kill -3 <python_pid> # 向主进程发送SIGQUIT信号 # 或使用工具(推荐安装到生产环境,但作为pip依赖) py-spy dump -p <pid> # 无侵入式查看线程栈
观察是否有死锁(看到多个线程互相等待
Lock)、或无限循环。 - 内存持续增长:
# 使用tracemalloc(Python 3.4+) # 或者在代码中动态开启 pip install objgraph # 生产环境小心:dumpp文件可能很大
查看是哪个对象(如DataFrame、缓存对象)大量堆积。
- 进程卡死/CPU高:
-
检查外部依赖
- 数据库连接池:检查
SQLAlchemy等配置,是否因未释放连接导致Too many connections。 - HTTP/Redis:检查
requests库或redis-py的超时设置是否过短(导致大量超时重试,雪崩)。
- 数据库连接池:检查
临时修复(Workaround)
- 重启:针对内存泄漏、连接池耗尽:
systemctl restart your_python_app。 - 扩容:启动更多Python进程(GIL原因,多进程比多线程对CPU密集型应用更有用)。
- 限流:为API添加限流(如Flask-Limiter),避免被突发请求打垮。
- 修改配置:临时调大
asyncio的semaphore限制,或日志级别改为ERROR。
永久修复与复盘
- 修复:写单元测试/集成测试,确保修复补丁不会引入回归。
- 复盘要点:
- 依赖锁定:是否因为没有使用
poetry.lock或pip freeze导致环境不一致? - 异常捕获:是否所有IO操作(网络、磁盘)都有
try-except?except Exception是否隐藏了严重错误? - 代码审查:是否有慢查询或未优化的循环?
- 依赖锁定:是否因为没有使用
预案文档必备清单
你的应急预案文档(Runbook)应包含以下关键内容:
- 联系方式:值班人员、Python核心开发者、第三方库(如数据库)DBA的联系方式。
- 部署拓扑图:代码仓库地址、CI/CD流水线地址、部署实例清单及其IP。
- 关键命令集:
# 重启服务 sudo systemctl restart your-app.service # 查看实时日志(关注ERROR和CRITICAL) journalctl -u your-app -f -n 100 | grep -i error # 进入生产环境Python解释器 cd /opt/your_app && source venv/bin/activate && python # 查看所有进程及状态 supervisorctl status # 回滚操作 git checkout v1.2.3 pip install -r requirements.txt sudo systemctl restart your-app
- 健康检查端点:
curl http://localhost:8080/health应返回HTTP 200。 - 放火测试(Chaos Engineering):定期在预发环境模拟依赖中断(如断开数据库网络),验证降级逻辑是否生效。
黄金法则
- 不要在生产环境直接 debug:如果问题复杂,优先回滚或重启,不要试图在服务器上改代码。
- 日志是命根子:务必记录
timestamp、trace_id、exception_type、stack_trace。不要只打except: pass。 - 资源限制:对Python进程设置
ulimit(文件句柄限制)和内存限制(Docker的--memory),防止单个进程拖垮整个服务器。 - 测试你的预案:每季度进行一次故障演练(GameDay),模拟“依赖库被投毒”、“磁盘写满”、“连续内存泄漏”等场景,确保团队会执行上述流程。
- 通用部分:回滚、重启、监控、告警,与其他语言应用无异。
- Python特色:重点关注 GIL(多核利用率)、内存管理(引用循环)、依赖冲突(pip地狱) 和 异步编程(协程死锁)。
- 核心工具:
py-spy(线程栈)、tracemalloc(内存追踪)、supervisor(进程管理)、pip freeze(依赖锁定)。