1. 引言:为什么需要一个「诊疗室」
线上系统突然变慢、接口偶发 500、数据库连接池莫名耗尽......这些问题往往没有明确报错,日志里也看不出端倪。本文把这类问题统称为「IT 疑难杂症」,并尝试用一套类似医院问诊的流程来系统化地定位与解决。
2. 疑难杂症的典型特征
- 偶发性:无法稳定复现,压测环境一切正常
- 跨层性:问题表象在应用层,根因可能在网络、内核或存储
- 信息缺失:日志被截断、监控指标粒度不够、链路追踪未覆盖
- 时间压力:故障持续期间业务损失随时间线性增长
3. 诊疗室的分诊机制:先分类,再定位
3.1 按现象分诊
| 现象 | 可能方向 | 首选排查手段 |
|---|---|---|
| 响应变慢 | 资源瓶颈 / 锁竞争 / 慢 SQL | 火焰图、慢查询日志 |
| 偶发报错 | 并发问题 / 超时 / 依赖抖动 | 链路追踪、错误聚合 |
| 内存持续上涨 | 内存泄漏 / 缓存无上限 | 堆转储、GC 日志 |
| 连接数打满 | 连接未释放 / 下游阻塞 | 连接池监控、线程栈 |
3.2 按影响面分诊
先判断是单实例、单机房还是全站问题,影响面决定了排查的优先级与止损策略。
4. 标准问诊流程
#mermaid-svg-W0c8SVyzbE5HWilX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-W0c8SVyzbE5HWilX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-W0c8SVyzbE5HWilX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-W0c8SVyzbE5HWilX .error-icon{fill:#552222;}#mermaid-svg-W0c8SVyzbE5HWilX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-W0c8SVyzbE5HWilX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-W0c8SVyzbE5HWilX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-W0c8SVyzbE5HWilX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-W0c8SVyzbE5HWilX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-W0c8SVyzbE5HWilX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-W0c8SVyzbE5HWilX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-W0c8SVyzbE5HWilX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-W0c8SVyzbE5HWilX .marker.cross{stroke:#333333;}#mermaid-svg-W0c8SVyzbE5HWilX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-W0c8SVyzbE5HWilX p{margin:0;}#mermaid-svg-W0c8SVyzbE5HWilX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-W0c8SVyzbE5HWilX .cluster-label text{fill:#333;}#mermaid-svg-W0c8SVyzbE5HWilX .cluster-label span{color:#333;}#mermaid-svg-W0c8SVyzbE5HWilX .cluster-label span p{background-color:transparent;}#mermaid-svg-W0c8SVyzbE5HWilX .label text,#mermaid-svg-W0c8SVyzbE5HWilX span{fill:#333;color:#333;}#mermaid-svg-W0c8SVyzbE5HWilX .node rect,#mermaid-svg-W0c8SVyzbE5HWilX .node circle,#mermaid-svg-W0c8SVyzbE5HWilX .node ellipse,#mermaid-svg-W0c8SVyzbE5HWilX .node polygon,#mermaid-svg-W0c8SVyzbE5HWilX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-W0c8SVyzbE5HWilX .rough-node .label text,#mermaid-svg-W0c8SVyzbE5HWilX .node .label text,#mermaid-svg-W0c8SVyzbE5HWilX .image-shape .label,#mermaid-svg-W0c8SVyzbE5HWilX .icon-shape .label{text-anchor:middle;}#mermaid-svg-W0c8SVyzbE5HWilX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-W0c8SVyzbE5HWilX .rough-node .label,#mermaid-svg-W0c8SVyzbE5HWilX .node .label,#mermaid-svg-W0c8SVyzbE5HWilX .image-shape .label,#mermaid-svg-W0c8SVyzbE5HWilX .icon-shape .label{text-align:center;}#mermaid-svg-W0c8SVyzbE5HWilX .node.clickable{cursor:pointer;}#mermaid-svg-W0c8SVyzbE5HWilX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-W0c8SVyzbE5HWilX .arrowheadPath{fill:#333333;}#mermaid-svg-W0c8SVyzbE5HWilX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-W0c8SVyzbE5HWilX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-W0c8SVyzbE5HWilX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-W0c8SVyzbE5HWilX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-W0c8SVyzbE5HWilX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-W0c8SVyzbE5HWilX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-W0c8SVyzbE5HWilX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-W0c8SVyzbE5HWilX .cluster text{fill:#333;}#mermaid-svg-W0c8SVyzbE5HWilX .cluster span{color:#333;}#mermaid-svg-W0c8SVyzbE5HWilX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-W0c8SVyzbE5HWilX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-W0c8SVyzbE5HWilX rect.text{fill:none;stroke-width:0;}#mermaid-svg-W0c8SVyzbE5HWilX .icon-shape,#mermaid-svg-W0c8SVyzbE5HWilX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-W0c8SVyzbE5HWilX .icon-shape p,#mermaid-svg-W0c8SVyzbE5HWilX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-W0c8SVyzbE5HWilX .icon-shape .label rect,#mermaid-svg-W0c8SVyzbE5HWilX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-W0c8SVyzbE5HWilX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-W0c8SVyzbE5HWilX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-W0c8SVyzbE5HWilX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 单实例
全站
能
不能
现象收集
影响面判断
实例级排查
依赖与基础设施排查
指标与日志比对
能否复现
最小化复现环境
加埋点与观测
根因验证
修复与回归
复盘与沉淀
4.1 现象收集
明确「什么时候开始、影响谁、报什么错、最近有什么变更」,变更清单往往是最快的线索来源。
4.2 观测与取证
- 指标:CPU、内存、GC、线程数、连接数、QPS、P99 延迟
- 日志:错误聚合、关键路径打点、上下游耗时
- 链路:分布式追踪中的长尾 Span
- 现场:线程栈、堆转储、网络抓包
4.3 假设与验证
每次只验证一个假设,用可观测数据证伪或证实,避免同时改动多个变量。
5. 常见疑难杂症案例库
5.1 案例一:接口偶发超时
从「下游耗时正常但上游超时」出发,最终定位到连接池等待时间未计入超时预算。
5.2 案例二:内存缓慢泄漏
通过对比多次堆转储的对象增长,锁定未关闭的监听器注册。
5.3 案例三:CPU 使用率周期性飙升
结合定时任务时间点与火焰图,发现全量缓存刷新导致的瞬时计算峰值。
6. 工具箱:诊疗室常用器械
- 观测:Prometheus + Grafana、SkyWalking / Jaeger
- 诊断:Arthas、async-profiler、jstack、jmap
- 数据:慢查询日志、EXPLAIN、执行计划分析
- 网络:tcpdump、mtr、ss
7. 复盘与知识沉淀
- 建立故障档案:现象、根因、修复动作、验证方式
- 把一次性排查手段固化为监控告警与自动化巡检
- 沉淀「症状 → 检查项」的排查清单,缩短下次定位时间
8. 总结
疑难杂症的本质是信息不足与假设混乱。诊疗室的价值不在于某个神奇工具,而在于把「收集现象 → 分诊 → 取证 → 验证 → 复盘」变成可复用的流程。