第4章 异常处理与错误日志

异常处理与错误日志是生产环境稳定运行的基石。面试官通过本章考察候选人对异常机制的理解深度、日志等级的工程化设计能力、以及错误监控的实战经验。掌握结构化回答框架,让面试官看到你的「故障免疫力」。

异常处理黄金法则:及时捕获 · 准确记录 · 合理转化 · 快速失败 · 优雅降级

知识结构:PSR-3 日志等级对照表

等级名称典型使用场景生产告警
DEBUG调试开发环境 SQL 查询、变量值输出❌
INFO信息正常业务流程:登录、下单、支付回调❌
NOTICE通知正常但需关注:缓存失效、兜底策略触发❌
WARNING警告潜在风险:重试、降级、限流触发✅ 实时
ERROR错误运行时需处理:DB 连接失败、API 超时✅ 实时
CRITICAL严重核心功能不可用:订单服务宕机✅ 电话+群
ALERT警报需人工立即介入:磁盘写满、OOM✅ 电话+群
EMERGENCY紧急系统整体不可用:服务器崩溃✅ 全员
面试加分:主动说出「我按 PSR-3 规范设计日志等级,WARNING 以上对接实时告警,INFO 用于业务审计,DEBUG 仅开发环境开启」,体现工程化和运维思维。
识别异常类型 分层捕获处理 规范记录日志 监控告警通知 根因分析优化 图:异常处理面试回答框架 —— 从识别到根因闭环 异常处理设计 自定义异常类 日志等级划分 监控告警方案 性能优化策略 继承体系? 如何降噪? 误报控制? IO 瓶颈? 图:异常处理追问路径 —— 面试官常见深入方向

问答卡片 ① 异常处理机制

面试问题:请谈谈PHP中的异常处理机制,以及你在项目中如何设计异常处理?
面试官考察点:① 对异常体系的理解深度 ② 工程化设计能力 ③ 是否具备统一异常处理意识
回答框架:异常分类 → 分层捕获 → 自定义异常 → 统一响应
示例回答:我按业务异常与系统异常分类,使用 try-catch 分层捕获,自定义 BaseException 基类继承 \Exception,统一记录完整上下文日志并返回规范 JSON 响应,通过 Sentry 实时告警。
可能追问:① 业务异常和系统异常如何区分? ② 如何处理未捕获异常? ③ 自定义异常类如何设计继承链?
避坑提醒:不要吞没异常(空 catch),不要在 catch 中只写 log 不处理;区分「该抛的异常」和「该吞的异常」。

问答卡片 ② 日志系统设计与等级规范

面试问题:如何设计 PHP 项目的日志系统?日志等级如何划分?
面试官考察点:① 日志体系设计能力 ② 运维意识 ③ 是否了解行业规范
回答框架:等级划分 → 存储方案 → 格式规范 → 轮转策略
示例回答:采用 PSR-3 标准配合 Monolog,按日切割存储至 OSS,统一 JSON 格式包含 trace_id、模块、耗时。WARNING 以上对接钉钉群告警,ERROR 以上触发电话告警,INFO 用于业务审计。
可能追问:① 日志写入如何避免阻塞业务? ② 日志文件膨胀怎么处理? ③ 敏感信息如何脱敏?
避坑提醒:严禁记录明文密码/身份证号;日志目录需设置磁盘限额;切勿将 DEBUG 日志带到生产环境。

问答卡片 ③ 错误监控与生产排查

面试问题:生产环境出现 500 错误,如何快速定位和排查?
面试官考察点:① 问题排查实战能力 ② 监控体系理解 ③ 链路追踪意识
回答框架:监控定位 → 日志查询 → 链路追踪 → 根因分析
示例回答:先查 Sentry 错误聚合按频率排序定位异常接口,再根据 trace_id 到 ELK 搜索完整日志链路,分析请求参数与堆栈,最后结合 APM 看 DB 慢查询或 Redis 异常,定位后灰度修复。
可能追问:① 如何区分网络层错误与应用层错误? ② ELK 中日志字段如何设计? ③ 没有 trace_id 怎么处理?
避坑提醒:不要只看单条日志,要拉时间窗口聚合;注意区分业务异常(如参数校验失败)和系统异常;排查时先确认自身服务,再依赖上游。
核心原则:异常处理要「抓得住、记得住、报得出、查得到」。面试时展示从捕获到闭环的完整链路思维,比单独讲语法高出一个层级。

项目案例:电商平台订单服务错误监控体系

维度内容
项目名称电商平台订单服务错误监控与可观测性体系
业务背景618 大促期间订单量激增,需在分钟级发现和定位异常,保障 99.99% 可用性
规模指标峰值 QPS 5000+,日订单量 200 万+,30+ 服务节点,日均日志量 150 GB
技术栈PHP 8.1 + Laravel + Sentry + ELK + Prometheus + Grafana + RabbitMQ
核心难点① 分布式环境 trace_id 跨服务透传 ② 日志量大海捞针 ③ 告警噪音过多
面试高频追问① trace_id 如何通过 HTTP 和 MQ 透传? ② 告警阈值如何设定避免误报? ③ 日志量过大如何降本增效?
可迁移回答话术「在中间件入口生成 trace_id 注入上下文,通过 HTTP 头 + MQ 消息属性透传,确保全链路可回溯;告警基于 P99 历史数据动态基线计算,配合 Grafana 看板实现分钟级发现;冷日志归档至 OSS 低频存储,热日志保留 7 天。」
⛔ 常见踩坑:项目案例切忌只讲业务功能,要突出「稳定性设计」。面试官在异常处理章节,想听的是你如何让系统「扛得住、查得清、恢复快」。
背诵关键句:「异常处理不是 catch 后写日志就结束,而是从分类、捕获、记录、告警到根因分析的完整闭环。」—— 这句话放在每个回答结尾,都会让面试官点头。