🏁 结束原因:活干完了没、怎么死的(内存盘 3 图)

在途面板回答「正在干几个」,本组三张面板回答「干成了没、怎么死的」:outcome 是 Counter,配 rate by (outcome) 看每秒到达各结局的速率;exception 高时,失败重试会反复占内存。覆盖内存盘 🏁 结束原因组 3 张面板(m111 m112 m122)· 仪表盘 siliang-memory。

成功 着火 重试 结束原因 —— 每个活都有结局:干完了没、怎么死的 m111 · 文件/媒体三类活 ZIP 打包(archive) 视频转存(video_transfer) TTS 音频(tts) m112 · 快照/skill 两类活 快照合成(snapshot_compose) skill 整包(openapi_skill_package) m122 · 画布图片裁剪结果 正在处理几个 → 看 m107(在途) 这里只看:干得成不成功 …_workspace_crop_outcome_total 结局登记簿 outcome(Counter,_total) rate(x[5m]) by (outcome) 每秒有多少活到达各结局 只加不删 → 求「到达速率」 绝对值永远上扬,无信息量 成功(completed) 活干完了,内存该还就还 着火(exception) 重试 = 同一活再占一遍内存 与 RSS、在途面板三角互证 偶发成刺正常;持续一堆 = 频繁失败 动作:翻日志修根因,必要时限流重试 失败率 = exception 速率 ÷ 总结局速率 三角互证:exception 速率高 + RSS 冲高 + 在途挂着 = 失败重试在放大内存占用 失败任务的重试会反复占内存——exception 速率与 RSS 曲线对时间戳,常能看到联动 读法:结局是 Counter(_total)配 rate;「正在处理几个」看在途面板,「干成没」看本组——两个问题别混

💡 一句话理解

餐厅的出餐口有一本登记簿:每一单做完都要记一笔结局——正常出餐,或者厨房着火倒掉(exception)。内存盘的「结束原因」组就是六种活的出餐登记簿:m111 记文件/媒体三类(ZIP 打包、视频转存、TTS 音频),m112 记快照合成与 skill 整包,m122 记画布裁剪。

登记簿只加不删(Counter),所以要看的是"每秒有多少活到达各结局"——rate by (outcome)。而着火的单子最要命的不是难吃,是要重做:重做会再占一遍内存。所以 exception 高时,别只当可用性问题——拿它和 RSS、在途面板做三角互证,看失败是不是在放大内存压力。

🧩 费曼拆解 讲给完全没接触过的小白

先懂登记簿的机制。上一课的在途面板像"灶位占用表"——正在炒的有几单;本课的结局面板像"出餐登记簿"——做完的单子记上一笔:成了还是砸了。登记本是 Counter(名字带 _total,只加不删),所以直接画绝对值是一条永远上扬的直线,毫无信息量;配 rate(…[5m]) 再 by (outcome) 拆开,才是"每秒出几单、着几把火"的实时节奏。

六种活对三张图。m111 是热菜组三口灶(ZIP 打包 / 视频转存 / TTS 音频),m112 是冷菜组两个工(快照合成 / skill 整包),m122 是裁剪专柜——注意裁剪专柜有两本账:占几个灶位看 m107(在途),干得成不成功看 m122(结局)。「正在干几个」和「干成了没」是两个问题,由两组面板分工回答,混了就会看错现场。

最后是着火的连锁反应。exception 高不只是"失败率高":着火的单子不能端给客人,要倒掉重做——重做会再占一遍灶位(同一个活把大块内存重新攥一遍)。如果失败原因不修,重试会一直烧下去,内存被反复冲高。所以看到 exception 速率高的时段,把 RSS 曲线和在途线拉来对时间戳:三者联动 = 失败在放大内存占用,处置是修根因、必要时限流重试,而不是扩内存。

类比里的东西系统里对应的东西
出餐口登记簿outcome Counter(_total 只加不删):每个活结束时按结局记一笔
每秒出几单、着几把火rate(…outcome_total[5m]) by (outcome):到达各结局的速率
热菜组三口灶m111:ZIP 打包 / 视频转存 / TTS 音频三类活的结局
冷菜组两个工m112:快照合成 / skill 整包两类活的结局
裁剪专柜的两本账m122 看结局(干成没);占几个灶位看 m107(在途)——两问分工
着火重做再占灶位exception 高 → 重试反复占内存:与 RSS、在途面板三角互证

🛠 动手验证(4 步,在 Grafana 里亲手做一遍)

  1. 打开 m111——成功线应占绝对主力;exception 偶发成刺属正常。
  2. 看 m112——快照合成与 skill 整包同理;留意最近有没有 exception 持续冒头。
  3. 对照 m107 与 m122——裁剪"正在处理几个"和"成功速率"应该是联动的:在途有活,结局才有到达。
  4. 挑一个 exception 冒头的时段——把 m101 的 RSS 拉到同一时间轴:冲高与着火对上了吗?对上就是重试在放大内存。

🧠 必知必会 看懂本课全部面板的地基

结局是 Counter
outcome_total 只加不删(里程表),必须配 rate 看"到达速率";画绝对值是一条无意义的上扬线。
# 统一模板:Counter → rate → by (outcome)
sum by (outcome) (rate(…_outcome_total[5m]))
by (outcome) 拆线
不拆就是"总出餐速率",看不出着火比例;by (outcome) 才把成功与着火分成两条线。
# 模板带维度:每秒到达各结局的活数
sum by (outcome) (rate(siliang_workspace_crop_outcome_total[5m]))
六种活的分工
m111 管文件/媒体三类,m112 管快照/skill 两类,m122 管画布裁剪——六本登记簿各记各的。
# m111 口径(照抄主图谱:三类并列)
sum by (outcome) (rate(siliang_file_batch_archive_outcome_total[5m]))
# 同款:…_video_transfer_outcome_total / …_tts_outcome_total
在途 vs 结局
「正在干几个」是在途(Gauge,看 m106/m107);「干成了没」是结局(Counter 配 rate,本组)。两个问题两组面板。
# 裁剪专柜示范:两本账对照
max_over_time(siliang_workspace_crop_active[1m])  # 在途
sum by (outcome) (rate(siliang_workspace_crop_outcome_total[5m]))  # 结局
重试的内存代价
失败任务的重试会反复占内存:同一活把大块内存重新攥一遍——exception 速率与 RSS 对时间戳常能对上联动。
# 三角互证的三个角
sum by (outcome) (rate(…_outcome_total[5m]))       # 着火速率
max_over_time(…_resident_memory_bytes[1m])          # RSS 冲高
max_over_time(siliang_file_batch_archive_active[1m]) # 在途挂着
失败率的算法
失败率 = exception 速率 ÷ 总结局速率;单看 exception 绝对速率会被流量大小骗。
# 例:裁剪失败率
sum by (outcome) (rate(siliang_workspace_crop_outcome_total[5m]))
  / ignoring(outcome) sum(rate(siliang_workspace_crop_outcome_total[5m]))
刺 vs 持续高
偶发的 exception 刺是生活;持续一堆 = 频繁失败——翻日志修根因,必要时给重试限流。
# 判读:
# 单根刺   → 容忍,记录
# 持续非零 → 修根因 + 限流重试,别扩内存

📋 逐面板精讲 3 张图一张不落

🏁 m111 · 文件/媒体模块结束原因

它是什么:ZIP 打包 / 视频转存 / TTS 音频三类活的结局登记簿——每类按成功 / exception 拆线,速率含义是"每秒有多少个活到达该结局"。这三类活都是上一课"大对象在途"里的搬运工,箱子一个比一个沉。

回答什么问题:这三类活的失败率高不高?着火的是哪一类?

✅ 成功线占绝对主力,exception 偶发成刺;速率与对应业务量同步起伏

🚨 exception 高 = 频繁失败;失败任务的重试会反复占内存。动作:和 RSS、在途面板三角互证——三者联动就先修失败根因,必要时限流重试

# 面板 PromQL(照抄主图谱口径:三类并列)
sum by (outcome) (rate(siliang_file_batch_archive_outcome_total[5m]))
# 同款:…_video_transfer_outcome_total / …_tts_outcome_total

联动:主图谱 m111 ↗ · 相关课程:大对象在途(同一批活的灶位表) · rate():算速度

🏁 m112 · 快照/skill 模块结束原因

它是什么:快照合成 / skill 整包两类活的结局登记簿,读法与 m111 完全同款:rate by (outcome) 看每秒到达各结局的速率,成功为主、exception 偶发是健康像。

回答什么问题:快照与整包这两类活干得顺不顺?最近有没有在持续着火?

✅ 成功速率平稳、与业务节奏同步;exception 只有偶发刺

🚨 exception 持续非零 = 这两类活在频繁失败——重试会反复占内存(快照合成可是攥着多张图层的大活)。动作:翻日志定位根因,RSS 曲线对时间戳确认放大效应

# 面板 PromQL(照抄主图谱口径:两类并列)
sum by (outcome) (rate(siliang_snapshot_compose_outcome_total[5m]))
# 同款:…_openapi_skill_package_outcome_total

联动:主图谱 m112 ↗ · 相关课程:字节分布(快照源图多大号) · 大对象在途

✂️ m122 · 画布图片裁剪结果

它是什么:画布裁剪活的结局速率(成功 / exception 拆线)。注意分工:正在处理几个看前面"图像处理在途"卡(m107),这张图只回答"干得成不成功"。

回答什么问题:裁剪活的成功率怎么样?用户点裁剪之后是拿到结果还是吃到报错?

✅ 成功速率与裁剪请求量同步;exception 偶发

🚨 exception 持续冒头 = 裁剪在批量失败——图片解码是内存大户,失败重试会反复做解码。动作:与 m107 在途、m101 RSS 三角互证后修根因

# 面板 PromQL(照抄主图谱口径)
sum by (outcome) (rate(siliang_workspace_crop_outcome_total[5m]))

联动:主图谱 m122 ↗ · 相关课程:图像处理在途(m107 配对面板) · 图像/整包字节分布

🏭 生产实战 real world

场景 1 · exception 高的排查 SOP(先分火源再灭火)

着火先找是哪口灶,再翻对应日志——六种活六本登记簿,别一锅查。

# 第 1 步:分火源——三类文件/媒体活谁的 exception 在烧(m111 口径)
sum by (outcome) (rate(siliang_file_batch_archive_outcome_total[5m]))
sum by (outcome) (rate(siliang_video_transfer_outcome_total[5m]))
sum by (outcome) (rate(siliang_tts_outcome_total[5m]))
# 第 2 步:算失败率(分母=总结局速率),排除"流量大导致的绝对值高"
sum by (outcome) (rate(siliang_tts_outcome_total[5m]))
  / ignoring(outcome) sum(rate(siliang_tts_outcome_total[5m]))
# 第 3 步:按指标名定位模块 → 翻该模块日志修根因
# 判读:偶发刺容忍;持续非零 = 根因未修,限流重试只是止血

场景 2 · 失败重试的内存放大:三角互证查询组

本课最重要的联动:三个角一起看,着火是否在烧内存。

# 角 1:着火速率(m111 视频转存为例)
sum by (outcome) (rate(siliang_video_transfer_outcome_total[5m]))
# 角 2:RSS 曲线(m101 口径)
max_over_time(siliang_process_resident_memory_bytes{job="siliang_backend_worker"}[1m])
# 角 3:在途挂着(m106 口径,同一/相关模块的在途线)
max_over_time(siliang_file_batch_archive_active[1m])
max_over_time(siliang_image_segmentation_active[1m])
# 判读:三者同时段联动 = 失败重试在放大内存;处置 = 修根因 + 限流重试

判读收尾:在途与结局必须来自同一模块的配对面板——先在主图谱确认该模块的在途指标名,别张冠李戴。

场景 3 · 每周全模块结局巡检:六本登记簿一页看完

把六条查询钉进一页看板,每周扫一眼失败形态。

# m111 三类
sum by (outcome) (rate(siliang_file_batch_archive_outcome_total[5m]))
sum by (outcome) (rate(siliang_video_transfer_outcome_total[5m]))
sum by (outcome) (rate(siliang_tts_outcome_total[5m]))
# m112 两类
sum by (outcome) (rate(siliang_snapshot_compose_outcome_total[5m]))
sum by (outcome) (rate(siliang_openapi_skill_package_outcome_total[5m]))
# m122 一类
sum by (outcome) (rate(siliang_workspace_crop_outcome_total[5m]))
# 巡检标准:全部 success 为主、exception 仅偶发刺 = 过关

场景 4 · 发布后验证:结局速率恢复才算修好

修复上线后,除了看哨兵归零,还要看结局速率回到健康形态。

# 上线后 30 分钟观察(以裁剪为例)
sum by (outcome) (rate(siliang_workspace_crop_outcome_total[5m]))
# 验收标准:
#   1. exception 速率回落到发布前基线(只剩偶发刺)
#   2. 成功速率与请求量恢复同步
#   3. RSS 不再因重试反复冲高(m101 对时间戳确认)
max_over_time(siliang_process_resident_memory_bytes[1m])

⚠️ 常见坑 pitfalls

坑 1 · 画结局绝对值 — 症状:把 outcome_total 直接画成曲线,一条永远上扬的直线。原因:Counter 只加不删,绝对值无信息量。正解:配 rate 看到达速率,这是这类面板的唯一正确打开方式。
# 错: siliang_tts_outcome_total
# 对: sum by (outcome) (rate(siliang_tts_outcome_total[5m]))
坑 2 · 忘 by (outcome) — 症状:rate 出来一条线,看不出成功还是失败。原因:所有结局被加总,着火被出餐淹没。正解:by (outcome) 拆线,成功与着火各一条。
# 错: sum(rate(…_outcome_total[5m]))
# 对: sum by (outcome) (rate(…_outcome_total[5m]))
坑 3 · 只看成功速率不看来失败占比 — 症状:"成功速率没掉,没事"。原因:流量涨时失败也涨,但占比可能恶化;成功率才是质量。正解:失败率 = exception ÷ 总结局速率,一起看。
# 错: 成功线还在涨 → 健康
# 对: exception 速率 ÷ 总速率 → 看占比趋势
坑 4 · 偶发刺当事故 — 症状:一根 exception 刺就升级排障。原因:任何活都有偶发失败,刺是生活。正解:偶发记录观察;持续非零才立案修根因。
# 错: 看到 exception > 0 就呼叫值班
# 对: for: 10m 持续非零才触发,刺用眼睛过滤
坑 5 · 失败只顾重试不限流 — 症状:着火后把重试次数调到最大"保成功率"。原因:每次重试都重新攥一遍大内存,根因不修时重试=反复放火。正解:先修根因,重试要有上限与退避。
# 错: 失败 → 无限重试保成功率
# 对: 修根因 + 重试上限/退避,内存才不被反复冲
坑 6 · m122 与 m107 混为一谈 — 症状:在 m122 里问"现在有几个裁剪在处理"。原因:m122 是结局(干成没),m107 才是在途(正在干几个)。正解:两个问题两组面板:占灶位看 m107,出餐记录看 m122。
# 错: 从 outcome_total 读"当前在途数"
# 对: max_over_time(siliang_workspace_crop_active[1m])
坑 7 · exception 高直接定罪内存泄漏 — 症状:看到失败多 + 内存高,结论"泄漏"。原因:那是重试反复占内存的短期放大,不是"只进不出"的泄漏。正解:看 RSS 冲高后回不回落:回落/平台期=重试放大;线性爬升才走泄漏线。
# 错: exception 高 + RSS 高 → 泄漏实锤
# 对: deriv(RSS[1h]):≈0=重试放大;持续>5MB/h=泄漏线

🎓 费曼自测 合上书,能讲出来才算懂

Q1 · 在途面板和结束原因面板,分别回答什么问题?为什么两组都要有?

参考答案:在途(m106/m107)是灶位表,回答"此刻正在干几个活"——是 Gauge,健康形态是忙时跳起、闲时归零;结束原因(m111/m112/m122)是出餐登记簿,回答"干成的多还是砸的多"——是 Counter 配 rate 看到达速率。一个管现在、一个管结果:在途高而结局到达少=活堆着出不来;在途归零而 exception 高=干得快但砸得也快。两个问题必须两组面板分工。

Q2 · 为什么说 exception 高不只是"可用性问题",还是内存问题?

参考答案:因为着火的活要重做,重做会把同一批大对象重新攥一遍内存——视频转存、快照合成都是几十 MB 起步的大活。根因不修时,重试会反复冲高 RSS。三角互证:exception 速率高 + RSS 同步冲高 + 在途挂着,三者对上时间戳就说明失败在放大内存占用;处置是修根因、给重试加上限和退避,而不是扩内存。

Q3 · 结局面板查询的固定三件套是什么?漏了哪件会分别看到什么假象?

参考答案:rate、[5m](或其他窗口)、by (outcome)。漏 rate:Counter 绝对值永远上扬,毫无信息量;漏 by (outcome):成功与失败加总成一条线,着火被出餐淹没;窗口太短(如 [1m]):曲线毛刺化,偶发刺与持续失败难以区分。标准模板:sum by (outcome) (rate(…_outcome_total[5m]))。

← 上一课:📏 字节分布:大对象的典型体重 📚 课程目录 下一课:🔌 连接池台账:backend 视角 →