🔌 连接池台账:backend 视角(内存盘 6 图)

backend 干每件活都要向三家「图书馆」借资源:MySQL 三格书架、Redis 两张借书证、外网电话总机。台账=6 张图:借出数、容量上限、使用率、总机存活。覆盖 m113 · m115 · m116 · m117 · m118 · m119 · 后端内存仪表盘「🔌 连接池」组(内存盘 6 图)。

🔌 连接池台账:backend 干活前要借三家的书(每个 worker 各自一套) checked_out 借出 in_use 借出(两张证各算各) active 占线 · keep-alive 复用 backend worker(借书人) 每个 worker 独立一套池 · 4 worker 共 4 套 DB 池 · 三格书架 sync 30 · async 80 · checkpointer 30 Redis 池 · 两张借书证 shared 50(与 Agent 服务共用) broadcaster_pubsub(画布广播专用) httpx 出站总机 active=占线线路 · alive=总机在不在(1/0) MySQL(藏书墙) 书=连接 · 容量写在借书证上 Redis(广播与租约机房) 跨实例广播 · 任务租约都在这 LLM / COS 等外网电话局 gpt-5 · xAI · MiniMax · Seedance ① 使用率卡(看趋势 → 配告警) 使用率 = 借出 ÷ 藏书(checked_out ÷ capacity) 0 80% 黄 95% 红 贴 100% = 池打满,请求开始排队(通常伴随某个慢查询) ② 绝对值卡(看离天花板多远) 实线 = 各 worker 借出数 水平参考线 = 藏书量 sync 30 / async 80 / ck 30 实线贴参考线 = 快打满 事故现场 A · async 池 80/80 贴 100% 一个慢查询占着 80 条异步连接不还(书全借空) → 新请求排队等书 → 接口 P99 飙升 → 并发翻倍再压池 → 铁三角连环雪崩(先杀慢查询/限流,别急着调大池) 事故现场 B · provider 总机掉 0 有聊天流量时 alive 1→0 = 连接复用被回退 → 每次外呼都新建连接(TCP 握手 + TLS,几十 ms 起步) → FD 与内存抖动(对照内存盘线程/FD 面板互证) 读图顺序:先看使用率卡定罪(贴 80%?)→ 再看绝对值卡定位(哪个 worker 哪格书架)→ 最后看总机与存活(出站是否复用)

💡 一句话理解

连接池就是「图书馆借书制」:连接(书)提前建好一柜子,用的时候借(checked_out),用完就还;柜子总量就是藏书量(capacity),借光了后来的人排队等还书。backend 干每件活要借三家:跟 MySQL 借数据库连接(三格书架 sync 30 / async 80 / checkpointer 30)、跟 Redis 借两张借书证(shared 业务池上限 50,与 Agent 服务共用;broadcaster_pubsub 画布广播专用池)、对外打 HTTP 走 httpx 出站总机(active=占线几路,alive=总机还在不在)。

这 6 张图就是三家图书馆的借阅台账:每张卡回答同一件事——「书还够不够借」。书够,一切快;书借光(池打满),所有人排队,接口延迟跟着雪崩。

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

为什么要有池?因为「建一条连接」很贵:跟 MySQL 建连接要 TCP 握手加认证,跟外网建 HTTPS 还要再加 TLS 协商,几十毫秒起步——就像每次借书都现盖一座图书馆。所以程序启动时就建好一柜子连接反复借还。四两 backend 的书柜分三格:sync 30(同步查询)、async 80(异步查询并发高,同一瞬间要借的书最多,所以格子最大)、checkpointer 30(检查点写库走独立书架,免得跟业务抢书)。

Redis 那边是两张借书证:shared 是业务共用池(上限 50,而且这本证还跟 Agent 服务合用——对方用得多,你的使用率也会被抬 high);broadcaster_pubsub 是画布广播专线(你在 A 机器画一笔,要靠它把消息发到 B 机器的同伴屏幕上),它打满 = 协作消息发不出去。最后是出站总机 httpx:到各家 provider 的电话线也是池化的,active 数占线,alive 说明总机本身还在不在——总机没了就退回「每打一通电话现拉一条线」,FD 和内存跟着抖。

台账有「两张卡」的分工(口径卡原话):使用率卡(借出÷藏书)看趋势、配告警,80% 黄、95% 红;绝对值卡(实线借出数 + 藏书量参考线)看离天花板还有几条。两张卡一起看:使用率告诉你「快不行了」,绝对值告诉你「还差几本到底」。

类比里的东西系统里对应的东西
借出的书checked_out(DB 池)/ in_use(Redis 池)/ active(httpx 占线)——正在干活的连接数
藏书量 / 借书证额度capacity:backend 三格书架 sync 30 / async 80 / checkpointer 30;Redis shared 上限 50
两张借书证Redis 的 shared(业务共用,与 Agent 服务共用)与 broadcaster_pubsub(画布广播专线)
出站电话总机httpx 共享 client:active=占线线路数,alive=总机在不在(1=存活,0=没了)
借阅告警线使用率 80% 黄 / 95% 红;贴 100% = 池打满,请求排队(通常伴随某个慢查询)
每家分店各一本账池是 per-worker 的:每个 worker 独立一套池,图上一条线 = 一个 worker 的一格书架

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

  1. 打开内存盘「🔌 连接池」组,先看使用率卡——确认没有任何一条线长期贴 80% 黄线;偶发高峰后回落是健康的。
  2. 切到绝对值卡——对照 sync 30 / async 80 / checkpointer 30 的水平参考线,亲眼看看「离天花板还有几条」。
  3. 看 Redis 使用率卡——分清 shared 与 broadcaster_pubsub 两条线:广播池贴 100% 就是协作事故,别跟业务池混着看。
  4. 最后看共享 HTTP client 存活——挑一段有聊天流量的时间,确认每条 provider 线都是 1;哪条掉 0,就是连接复用被回退了。

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

连接池三要素
借出数(checked_out / in_use)、藏书量(capacity)、使用率(借出÷藏书)。建连接贵(握手+认证),所以池化复用;借光就排队。
# 使用率的分子分母(DB 池)
siliang_db_pool_connections{state="checked_out"}   # 借出几条
siliang_db_pool_capacity                              # 藏书量(天花板)
backend 三格书架
sync 30 / async 80 / checkpointer 30。async 格子最大,因为异步并发高、同一瞬间借书的人最多;checkpointer 是独立写库的书架,和业务互不抢。
# 三格书架在图上是三条参考线(绝对值卡)
max by (pool) (siliang_db_pool_capacity)   # → sync=30, async=80, checkpointer=30
per-worker 口径
池是每个 worker 独立一套的。看图时一条线=一个 worker;做容量规划要乘 worker 数,别拿单 worker 的 30 当全机总额。
# 以 sync 格 30 条为例(per-worker)
30 × 4 worker = 120   # 整机实际能同时借出这么多,规划时要乘
两张卡用法
口径卡原话:使用率卡看趋势告警 + 绝对值卡看离天花板多远。使用率回答「危险吗」,绝对值回答「还差几条到底」。
# 使用率卡(趋势/告警)
max_over_time(siliang_db_pool_connections{state="checked_out"}[1m])
  / on(instance,pool) max_over_time(siliang_db_pool_capacity[1m])
Redis 双池
shared=业务共用池(上限 50,与 Agent 服务共用——对方挤占你也会高);broadcaster_pubsub=画布广播专用池,打满=协作消息发不出去。
# 两张借书证按 pool 标签分开看
siliang_redis_pool_connections{state="in_use"}   # by (instance, pool) 拆线
# → pool="shared" 业务池 · pool="broadcaster_pubsub" 广播池
80% 黄 / 95% 红
通用饱和度阈值,也是雪崩的刹车点:延迟一涨→并发翻倍→池更快打满→排队更狠。80% 就该找慢查询,别等 100%。
# 雪崩链条(铁三角)
# 延迟翻倍 → 并发翻倍 → 使用率贴 100% → 排队更狠 → 雪崩
# 所以 80% 是刹车点,不是参考建议
httpx 出站总机
到 LLM/COS 等外网的 HTTP 连接也是池化的(httpx 共享 client)。active=该 worker 正占用的线路数;按 worker 展开看不均衡。
# 每 worker 占用的出站线路(主图谱口径)
siliang_http_client_connections{state="active"} by (instance, client)
# → 某个 worker 独自飙高 = 它的任务在狂打外部请求
client 存活哨兵
alive=到各家 provider 的「总机」还在不在(1=在,0=没了)。连接复用是省内存省延迟的关键设计,掉 0 属于防回退哨兵报警。
# 总机存活(1=在)
max by (provider) (max_over_time(siliang_shared_http_client_alive[1m]))
# → 有聊天流量时出现 0 = 复用被回退,退回每次新建连接

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

🟣 数据库连接池使用率(worker × 池)

它是什么:借出书 ÷ 藏书量的百分比,按 worker × 池(sync / async / checkpointer)拆成多条线。这是 DB 图书馆的「饱和度」读数——告警配在它身上,因为百分比不受容量影响,三格书架可以放同一张图里比。

回答什么问题:哪个 worker 的哪格书架快借空了?打满的趋势是从什么时候开始的(常能对上一次发布或一条慢查询)?

✅ 健康长啥样:各线围绕低位波动(远低于 80%),偶有业务高峰冲一下就回落;三条线形态大体同步(业务忙大家都忙)。

🚨 危险长啥样:80% 黄、95% 红;某条线贴 100% = 池打满,请求开始排队(通常伴随某个慢查询)。动作:先找占着连接不还的慢查询 / 顺手看锁冲突面板,而不是无脑调大池。

# 主图谱口径:借出数 ÷ 容量,on(instance,pool) 保证分子分母对上同一条书架
max_over_time(siliang_db_pool_connections{state="checked_out"}[1m])
  / on(instance,pool)
  max_over_time(siliang_db_pool_capacity[1m])

联动:主图谱 · DB 池使用率 ↗ · 相关课程:连接池:图书馆借书 · QPS·并发·延迟铁三角 · 数据库锁冲突

🟣 数据库连接池借出数与容量上限

它是什么:上一张的绝对值版:实线是各 worker 此刻借了几条连接,水平参考线是该池的藏书量(sync 30 / async 80 / checkpointer 30)。它不告诉你「百分比危不危险」,但直观告诉你「离天花板还有几条」——调容量、估算余量时看这张。

回答什么问题:async 池现在借出 62 条还是 79 条?离 80 的天花板还剩多少缓冲?容量要不要调?

✅ 健康长啥样:实线在参考线下方从容起伏,高峰期也不贴线;三格书架的实线各自独立波动。

🚨 危险长啥样:实线贴平参考线(比如 async 顶在 80 不下来)= 该格书架被借空;配合使用率卡互证后动作:找慢查询、看锁冲突,而不是先动容量。

# 主图谱口径:实线=借出数,参考线=该池藏书量(sync 30 / async 80 / checkpointer 30)
siliang_db_pool_connections{state="checked_out"} + max by (pool) (siliang_db_pool_capacity)

联动:主图谱 · DB 池借出数与上限 ↗ · 相关课程:连接池:图书馆借书 · biz 盘的镜像双卡 b5/b6

🟣 Redis 连接池使用率

它是什么:Redis 图书馆的两张借书证各自的使用率:shared(业务共用池,上限 50,还与 Agent 服务共用)和 broadcaster_pubsub(画布广播专用池)。Redis 承载着 pubsub 跨实例广播、任务租约等要命的东西,所以它的池子要单独盯。

回答什么问题:Redis 是不是成了瓶颈?尤其:广播池打满了没有——它打满,画布协作消息就发不出去(你在 A 机器画,B 机器看不见)。

✅ 健康长啥样:两条线都远离 100%;shared 因与 Agent 服务共用会有「别人的波动」,形态偶发抬升后回落属正常。

🚨 危险长啥样:broadcaster_pubsub 贴 100% = 协作消息发不出,去核心盘 WS 错误面板看 redis_pubsub 是否 > 0(广播失明)互证;shared 持续高位但本服务没加流量 = 怀疑 Agent 侧挤占,别急着重启 Redis。

# 主图谱口径:Redis 池使用率(in_use ÷ capacity,按 instance × pool 拆)
max_over_time(siliang_redis_pool_connections{state="in_use"}[1m])
  / on(instance,pool) max_over_time(siliang_redis_pool_capacity[1m])

联动:主图谱 · Redis 池使用率 ↗ · 相关课程:WebSocket 画布协作 · biz 盘 b7/b8(同一台上限 50)

🟣 Redis 连接池借出数与上限

它是什么:Redis 池的绝对值版——各 worker 在 shared / broadcaster_pubsub 两张证上各借出几条,外加水平上限参考线。和 m116 一样,它是「数格子」的卡:看具体还剩几条额度。

回答什么问题:广播池现在借出几条、离上限还差几条?shared 池的高是均匀分布在各 worker,还是某一个 worker 独自借了一堆?

✅ 健康长啥样:实线远低于上限参考线;各 worker 借出数大体均匀(大家干的活差不多)。

🚨 危险长啥样:某条实线顶平参考线 = 该 worker 该池借空;广播池顶平立刻查协作链路(与 m117、WS 错误面板三角互证),业务池顶平先分清是自家流量还是 Agent 侧挤占。

# 主图谱口径:借出数(实线)+ 上限(参考线)
siliang_redis_pool_connections{state="in_use"} + max by (pool) (siliang_redis_pool_capacity)

联动:主图谱 · Redis 池借出数与上限 ↗ · 相关课程:连接池:图书馆借书 · WS 画布协作(广播链路)

🟣 HTTP client 借出连接(每 worker)

它是什么:出站电话总机(httpx 共享 client)上,每个 worker 正在占用的线路数。四两要跟 LLM、COS 等一堆外网说话,这些出站连接也是池化复用的——这张图就是总机的「占线指示灯」。

回答什么问题:哪个 worker 在狂打外部请求?(按 worker 展开,不均衡一眼可见。)下游是不是变慢了?(大家都占着线不放 = 外呼迟迟不挂。)

✅ 健康长啥样:各 worker 的线随业务节奏同起同落;外呼高峰占线多、过后回落。

🚨 危险长啥样:某个 worker 独自飙高 = 它身上的任务在狂打外部请求(对照后台任务/LLM 调用找来源);全员持续高位 = 下游变慢占着线路,去看 LLM 延迟与错误率面板互证。

# 主图谱口径:出站占线数,按 worker × client 拆
siliang_http_client_connections{state="active"} by (instance, client)

联动:主图谱 · HTTP client 借出连接 ↗ · 相关课程:LLM 健康门诊 · 铁三角(占线=并发)

🟣 共享 HTTP client 存活(1=存活)

它是什么:到各家 provider 的「电话总机」本身还在不在:1=在,0=没了。它是个防回退哨兵——「共享 client 连接复用」是省内存省延迟的关键设计,曾经有人把它改坏过(退回每次新建连接),这张图就是防止这种回退悄悄上线的警报器。

回答什么问题:连接复用的设计还在不在?发布之后总机有没有被改没了?

✅ 健康长啥样:有聊天流量的时段,每条 provider 线都稳稳贴在 1;没流量的低谷期波动无意义,别误读。

🚨 危险长啥样:有聊天流量时某 provider 掉 0 = 连接复用被回退——退回每次新建连接,FD 和内存跟着抖。动作:对照最近发布回查代码,同时看线程/FD 面板旁证。

# 主图谱口径:总机存活(抹抖动后按 provider 取最大)
max by (provider) (max_over_time(siliang_shared_http_client_alive[1m]))

联动:主图谱 · 共享 HTTP client 存活 ↗ · 相关课程:线程/FD 四件套(抖动旁证) · 防护与缓存(下游响应防线)

🏭 生产实战 real world

场景 1 · 下午三点接口集体变慢,第一个该看的图

症状:好几个不相关的接口 P99 同时抬头。常规做法是挨个翻接口日志——错,先看 DB 池:所有请求共用书架,书架借空是「集体变慢」最常见的公共原因。

# 第 1 步:看哪个 worker 的哪格书架在贴 100%(先定位再开药)
max_over_time(siliang_db_pool_connections{state="checked_out"}[1m])
  / on(instance,pool)
  max_over_time(siliang_db_pool_capacity[1m])
# → 每条线 = 一个 worker 的一格书架;贴 1.0 的就是打满点

# 第 2 步:打满通常是「占着书不还」的慢查询/锁,顺手对一眼锁冲突哨兵
sum(increase(siliang_db_lock_errors_total{job="siliang_backend_worker"}[1h]))
# → > 0:去锁冲突率面板按 operation, code 定位(1205=等太久,1213=死锁)

判读:使用率回落且锁冲突为 0,是流量高峰的正常挤压;使用率钉死 100% 不动,去日志找那条占着 80 条 async 连接的慢查询。

场景 2 · 「你画我看不见」:广播池打满事故

症状:用户反馈画布协作不同步。协作消息跨机器全靠 Redis 的 broadcaster_pubsub 广播池——它打满,消息就发不出去。

# 广播池使用率(pool 取值以图例为准:shared / broadcaster_pubsub)
max_over_time(siliang_redis_pool_connections{state="in_use",pool="broadcaster_pubsub"}[1m])
  / on(instance,pool)
  max_over_time(siliang_redis_pool_capacity{pool="broadcaster_pubsub"}[1m])

# 互证:核心盘 WS 错误类型里 redis_pubsub > 0 = 广播失明
sum(rate(siliang_ws_errors_total[5m])) by (error_type)

判读:池贴 100% 且 redis_pubsub 错误出现 = 实锤;广播池是专线,被业务池挤到的可能性低,优先查广播 subscriber 是不是堆积了。

场景 3 · 给 DB 池配上 80% 黄 / 95% 红两级告警

池打满到排队只是几秒的事,等人工发现就晚了。把通用阈值固化成两级告警(阈值为口径卡通用口径,for 时长按业务调整)。

# 示例告警规则(Prometheus rule YAML,阈值=主图谱通用口径)
groups:
- name: db-pool
  rules:
  - alert: DbPoolUsageHigh
    expr: max_over_time(siliang_db_pool_connections{state="checked_out"}[1m])
        / on(instance,pool) max_over_time(siliang_db_pool_capacity[1m]) > 0.80
    labels: {severity: warning}   # 黄:开始找慢查询
    annotations: {summary: "DB 池使用率 > 80%({{ $labels.instance }} / {{ $labels.pool }})"}
  - alert: DbPoolSaturated
    expr: max_over_time(siliang_db_pool_connections{state="checked_out"}[1m])
        / on(instance,pool) max_over_time(siliang_db_pool_capacity[1m]) > 0.95
    labels: {severity: critical}  # 红:贴 100% 就开始排队,P99 跟着起飞
    annotations: {summary: "DB 池使用率 > 95%,即将打满排队"}

场景 4 · 发布后确认「连接复用」没被改没了

背景:有人优化代码时把共享 client 换成了「每次请求 new 一个」——功能全对,性能悄悄劣化。m113 就是抓这种回退的哨兵。

# 有聊天流量的时段,每个 provider 的总机都应该是 1
max by (provider) (max_over_time(siliang_shared_http_client_alive[1m]))
# → 出现 0:连接复用被回退,退回每次新建连接(TCP 握手+TLS)

# 旁证:FD 与内存抖动会同步出现(对照内存盘线程/FD 面板)
max_over_time(siliang_process_open_file_descriptors[1m])
max_over_time(siliang_process_resident_memory_bytes[1m])

判读:alive 恒 1 且 FD 平稳 = 复用健在;alive 掉 0 且 FD 锯齿变粗 = 实锤回退,回查该时段的发布。

场景 5 · Redis 池莫名偏高,先问「是不是别人在用」

shared 池是和 Agent 服务合用的借书证——对方用得多,你的使用率也会高。看到 Redis 池高就重启 Redis,十有八九是打错靶子。

# shared 池使用率(与 Agent 服务共用,上限 50)
max_over_time(siliang_redis_pool_connections{state="in_use",pool="shared"}[1m])
  / on(instance,pool)
  max_over_time(siliang_redis_pool_capacity{pool="shared"}[1m])
# → 高但本服务没加流量:先对 Agent 侧用量与发布,别急着重启 Redis

# 对照:biz 仪表盘 b7/b8 是同一口径(上限 50,max_connections)
max_over_time(siliang_biz_redis_pool_connections{state="in_use"}[1m])

判读:两边同时抬高 = 共用方挤占或 Redis 本身变慢(借出去还得慢);只有一边高 = 查那边的流量来源。

场景 6 · checkpointer 池要单独看,别埋进「业务池」里

checkpointer(检查点)走的是独立书架(容量 30),和业务查询互不抢书——所以它的使用率波动节奏和 sync / async 不同步属正常,巡检时单独过一眼。

# 单独看 checkpointer 格的使用率(业务高峰它不跟涨是正常的)
max_over_time(siliang_db_pool_connections{state="checked_out",pool="checkpointer"}[1m])
  / on(instance,pool)
  max_over_time(siliang_db_pool_capacity{pool="checkpointer"}[1m])
# → 天花板 30:贴 100% = 检查点写库排队,和业务池打满是两种病

# 三格书架一屏总览(巡检收尾)
max by (pool) (max_over_time(siliang_db_pool_connections{state="checked_out"}[1m]))
  / on(pool) max by (pool) (max_over_time(siliang_db_pool_capacity[1m]))

判读:sync / async 随业务同步起伏、checkpointer 独立波动 = 三格书架各司其职;三格一起贴 100% = 数据库本身变慢(借了还不上),去查 DB 侧。

⚠️ 常见坑 pitfalls

坑 1 · 两张卡分工颠倒 — 拿绝对值卡配告警(「借出 > 70 条就报」),换容量后告警全错。原因:绝对值不含容量语义。正解:告警配在使用率卡(80%/95%),绝对值卡只用来回答「离天花板几条」。
# 错: siliang_db_pool_connections{state="checked_out"} > 70        # 写死绝对值,容量一改就废
# 对: max_over_time(…{state="checked_out"}[1m]) / on(instance,pool) …capacity[1m] > 0.80
坑 2 · 忘了 per-worker — 看到「sync 30」就以为整机只能借 30 条,做容量规划时严重低估。原因:池是每个 worker 独立一套的。正解:整机容量 = 单 worker 容量 × worker 数。
# 错: "sync 30,所以整机并发上限 30 个查询"
# 对: 30 × 4 worker = 120   # 一条线只代表一个 worker
坑 3 · Redis 池高就重启 Redis — shared 池使用率高就断定 Redis 有问题。原因:shared 与 Agent 服务共用,对方挤占也会抬高读数;而且池高≠Redis 病了,可能是借了还没来得及还。正解:先按 pool 分清 shared / broadcaster_pubsub,再分清是谁的流量。
# 错: systemctl restart redis        # 打错靶子,还把广播/租约一起抖掉
# 对: by (pool) 分线 → 对照本服务与 Agent 侧流量 → 再定性
坑 4 · m113 掉 0 没人理 — 「总机没了又不报错,能跑就行」。原因:掉 0 不报错但退回每次新建连接,FD 与内存抖动是慢性病。正解:有聊天流量时段出现 0 立刻当回退事故查。
# 错: 只盯 5xx 和延迟,alive 面板常年不看
# 对: 发布后看一眼 alive=1 + FD 平稳,两个旁证一起确认复用健在
坑 5 · 使用率 100% 就调大池 — 打满就加容量,几天后打得更狠。原因:池打满通常是症状,病根是那条占着连接不还的慢查询/锁。正解:先杀慢查询、看锁冲突面板,确认是流量真涨了才动容量。
# 错: async 80 → 160     # 慢查询还在,书多了也一样被占光
# 对: 先定位慢查询/锁 → 修复 → 观察使用率回落 → 再评估容量
坑 6 · 各池套用同一个绝对值阈值 — 给 checkpointer 池也设「借出 > 70 报警」,结果它容量才 30,永远误报或永远不报。原因:三格书架容量不同(30/80/30),绝对值没有可比性。正解:跨池比较只认百分比(使用率)。
# 错: checked_out > 70            # 对 checkpointer(30) 永假,对 async(80) 太晚
# 对: 使用率 > 0.80              # 三格书架通用
坑 7 · 相除时忘了 on(instance,pool) — 使用率算出天文数字或恒为小数。原因:两个指标都有 instance/pool 标签,不对齐就会笛卡尔积错配。正解:照抄主图谱的 / on(instance,pool) 写法。
# 错: connections / capacity                     # 标签没对齐,结果错配
# 对: max_over_time(connections[1m]) / on(instance,pool) max_over_time(capacity[1m])

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

Q1 · 用「图书馆」向产品经理解释:为什么 DB 池打满会让全站变卡?

参考答案:每次干数据库的活都要先「借一本书」(连接)。书提前买了一柜子反复借还,很便宜;但柜子就那么大(sync 30 / async 80 / checkpointer 30)。有人的书借着不还(慢查询),柜子借空后,后面所有人只能排队等还书——哪怕他只想查一行数据。于是所有接口一起变慢,这就是「池打满连坐」。

Q2 · 使用率卡和绝对值卡明明是同一个池,为什么要画两张?

参考答案:分工不同。使用率卡=借出÷藏书,是百分比,回答「危不危险」,三格书架能放一张图比,告警配在它身上(80% 黄 / 95% 红);绝对值卡=实线借出数+藏书量参考线,回答「离天花板还差几条」,调容量、估余量时看它。一张管趋势告警,一张管具体余量。

Q3 · broadcaster_pubsub 池打满,用户会看到什么现象?你按什么顺序查?

参考答案:广播池是画布协作的专线,打满=协作消息发不出去——用户看到「你画我看不见」的跨机器协作失明。顺序:先看 m117/m118 确认广播池贴 100%;再去核心盘 WS 错误面板看 redis_pubsub 是否 > 0 互证;最后查广播 subscriber 堆积的来源(对照 WS 消息收发 QPS)。

Q4 · 共享 HTTP client 存活从 1 掉到 0,为什么算事故而不仅是「少了条连接」?

参考答案:alive=0 说明「连接复用」这个设计被回退了——总机没了,每次外呼都要现拉一条线(TCP 握手+TLS,几十毫秒起步),FD 和内存跟着抖。它平时不报错、用户无感,是慢性劣化,所以专门设了这张哨兵图:有聊天流量时出现 0,就对照发布回查代码。

← 上一课:🏁 结束原因:活干完了没、怎么死的 📚 课程目录 下一课:🕸 WS 会话内存:登记簿与背包 →