ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

WuKongIM 聊天生命周期 Soak 第四阶段:Coordinator 协调编排与 Verdict 判定体系实现解析

WuKongIM 聊天生命周期 Soak 第四阶段:Coordinator 协调编排与 Verdict 判定体系实现解析
  • 即时通讯
  • 后端

【免费下载链接】WuKongIM

More than just IM 不只是即时通讯(IM)

项目地址:https://gitcode.com/gh_mirrors/wu/WuKongIM
点击查看免费下载

导读

本文围绕 2026-08-04-chat-lifecycle-soak-04-coordinator-verdict.md 展开,详解 WuKongIM 聊天生命周期(chat lifecycle)长时压测第四阶段的核心设计:如何在第四台专用主机上部署一个不持有任何流量 socket 的 Coordinator,协调三个独立 worker 完成固定压力(soak)与老化数据容量(aged-data capacity)两类运行,并为每个运行产出确定性的产品/测试框架判定(verdict)。读完本文,你将掌握 preflight 准入检查、固定组目录准备、worker 分配与全局速率授予、Channel 生命周期三态证明(loaded → 自然缺失 → reheat)、正确性/延迟/资源/集群四维阈值判定,以及连续 checkpoint 与脱敏报告生成的完整实现脉络。

该计划对应的实现已全部落地于仓库internal/bench/chatlifecycle/包(99 个 Go 文件),本文将把计划文档的每个任务步骤与真实源码逐一对应,做到"计划 + 实现 + 验证"三位一体。

一、总体架构:第四台主机的无流量 Coordinator

1.1 为什么需要独立的 Coordinator

计划的 Goal 明确要求三件事:

  • 协调三个独立 worker:三个压测 worker 必须被统一编排,避免各自为政导致负载形状漂移;
  • 证明可重复的全节点 Channel runtime 转换:即反复证明一个 Channel 在三个服务节点上先"加载",后"自然冷却消失",再通过真实 SEND 重新加载,且消息序号不中断;
  • 产出确定性判定:固定压力运行与老化数据容量运行都要有明确的product_failure/harness_invalid/infrastructure_failure/operator_stop等闭合分类,而非"压完看日志"。

为此,计划规定第四台主机专门运行 Coordinator。它的职责边界在 coordinator.go 中被实现为一条严格的状态机链:

preflight -> group setup -> worker assign -> worker start -> observe -> checkpoint/finalize

与常见的"主节点即压测节点"方案不同,Coordinator不持有任何流量 socket,只做校验、调度、轮询与证据归约。这意味着:

  • 原始身份(raw UID、具体 channel ID、bearer token、标记 payload)只存在于瞬时认证探针请求中;
  • 持久化报告只使用hash 与 sample index,从报告本身无法还原任何用户身份或频道身份;
  • Coordinator 进程崩溃不会导致流量失真,因为流量由三个 worker 独立承担。

1.2 技术栈与三个可插拔边界

计划列出的技术栈在源码中一一对应:

计划声明的技术要素仓库实现位置
Go Coordinator 状态机coordinator.go
现有 target/metrics/bench APIinternal/bench/target/client.go
Prometheus 文本解析disk_observer.go、cluster_observation.go、observer.go内嵌解析
受保护的 debug 端点preflight 中DebugConfig/DebugCluster/ForceGC调用
node_exporter 文件系统指标preflight.go中DiskReader与node_filesystem_*解析
worker HTTP 客户端worker_client.go
JSON 与 Markdown 报告report.go

Coordinator 对外只暴露极窄的接口(CoordinatorPreflight、CoordinatorGroupSetup、CoordinatorWorker、CoordinatorObserver、CoordinatorRunHooks),运行层通过这些窄接口执行已验证的计划——这正是 doc.go 声明的包设计意图:"it intentionally contains no target mutation, concrete transport, worker loop, or host credential logic",即本包只负责确定性模型、窄启动编排、有界消息验证与脱敏证据记录。

二、配置模型与正式/本地默认值

2.1 三组运行语义:Profile / Mode / Stage

在 types.go 中,一次运行由三个正交维度定义:

  • Profile:formal(固定正式负载)或local(缩小规模、保留集群拓扑与同步语义的本地 shakeout);
  • Mode:soak(执行配置好的生命周期长跑)或capacity(在老化 soak 证据之后进入容量阶梯);
  • Stage:formal(完整正式观测窗口)、rehearsal(完整规模但有界彩排窗口)、shakeout(缩减的本地验证窗口)。

计划文档中提到的profile: local_shakeout,在实现中对应ProfileLocal + StageShakeout的组合(见 defaults.go 的LocalConfig())。此外Config还要求RunID非空、Seed非零(保证确定性随机流不依赖隐式种子),RunDuration是仅限 CLI 的彩排时长覆盖,仓库 YAML 无法设置它。

2.2 正式配置默认值一览

FormalConfig() 是经过评审的正式负载默认值,下面按维度列出(也是计划中各项阈值在实现中的落点):

维度参数正式默认值
规模在线用户10,000
规模新增用户/天250,000
规模全局 SEND 速率2,000 msg/s
流量人/群流量占比90% / 10%
热点集person / group 频道8,000 / 2,000
拓扑逻辑 Slot 组 / Hash Slot12 / 256
拓扑Slot 副本 / Channel 副本3 / 3
容量每节点最大频道数50,000
组目录Small/Medium/Large/VeryLarge1,600 / 300 / 99 / 1(超大群 100,000 成员)
时间线预热 / checkpoint / 最终2 小时 / 24 小时 / 72 小时
磁盘最小数据文件系统500 GB(500_000_000_000字节)
磁盘安全停止空闲百分比5%
正确性整体首试失败率< 1/10,000
正确性任意一分钟窗口首试失败率≤ 1/1,000
延迟Hot SENDACK p99 / p99.9400 ms / 1 s
延迟Cold/reheat SENDACK p99 / p99.92 s / 5 s
延迟全量会话同步 p99 / p99.91 s / 3 s
资源forced-GC live-heap 斜率5% / 6 小时窗口
资源goroutine 斜率5% / 24 小时窗口
集群健康轮询 / 持续失败判负5 s / 30 s
集群热 Slot 复制滞后上限64 条 Raft entry
集群Leader 不均衡阈值20% / 10 分钟

说明:计划文档中 Hot SENDACK 的 p99 写的是 200 ms,当前仓库实现默认值为400 ms;数据文件系统下限计划写作 1,000,000,000,000 字节,实现默认值为500 GB。凡涉及阈值数值,以当前仓库 defaults.go 为准。

三、Task 1:正式 Preflight 与目标观测

计划第一阶段解决"流量开闸之前必须先证明环境合法"。实现分为 preflight(一次性准入)与 observer(连续观测)两条线。

3.1 拓扑与端点配置校验

preflight.go 的静态校验要求配置必须命名:

  • 三个 service-node 的 metrics/debug 端点;
  • 一个独立均衡的 HTTP API 观测池;
  • 一个另行独立均衡的 TCP gateway 池(GatewayTCPAddrs);
  • 三个 worker 端点;
  • 三个 host-metrics 端点,外加一个单独的 load-host 端点。

计划明确要求:拒绝复用 worker/service 地址,拒绝把 API 池直接复制成 gateway 池。preflight 在发起任何网络 I/O 之前先完成静态拓扑校验(Check中cfg.Validate()与 bench token 非空即先决条件)。

3.2 最小化 debug/metrics 解码

preflight 对每个 service node 依次调用:

  1. Healthz/Readyz:服务与就绪探活;
  2. DebugConfig:读取受保护的/debug/config,并与配置比对。matchesPreflightConfig精确断言12 个初始 Slot 组、256 个 hash slot、Slot 副本 3、Channel 副本 3、max_channels=50000(对应实现默认值);
  3. ForceGC:受保护的 forced-GC heap 触发,必须在指标抓取前执行,以保证 heap 样本干净;
  4. CheckMetrics:校验产品 Prometheus 指标(Go/process、运行时队列、Channel 激活拒绝、Channel 元数据创建)齐备;
  5. DebugCluster:读取/debug/cluster的 Slot leader/replica/ISR/lag 事实,与节点 ID 交叉核对。

计划强调"使用最小响应结构,避免 debug 端点未来新增字段破坏基准"——实现中所有解码都限定在最小的目标结构体集合内。

3.3 node_exporter 磁盘准入

preflight 通过DiskReader解析node_filesystem_avail_bytes与node_filesystem_size_bytes,按配置中显式给出的数据挂载点/设备标签(Mountpoint/Device)选取文件系统:

  • 缺失或重复匹配→harness_invalid(PreflightCodeDiskAmbiguous);
  • 低于 5% 空闲→infrastructure_failure(PreflightCodeDiskFree),并触发CoordinatedStop安全协调停止;
  • 容量不足(小于MinimumDataFilesystemBytes)→infrastructure_failure(PreflightCodeDiskCapacity)。

正式 profile 还额外要求 host/process 资源可观测(HostResourcesObserved、ProcessResourcesObserved及 systemd 进程角色校验),否则按disk_ambiguous拒绝。

3.4 五秒观测轮询与连续失败判定

observer.go 实现连续的集群健康观测:

  • 每5 秒(Observation.Cadence)轮询一轮 health/readiness/cluster 状态,一轮内三个节点的请求由独立 goroutine 并行发出;
  • 服务不可用连续 30 秒→product_failure(ObserverCodeServiceHealth);
  • 每个逻辑 Slot 组必须有 1 个 leader 与 3 个副本,热组(hot Slot group)的 ISR/复制滞后超出阈值(默认 64 条 entry)持续 30 秒 → 失败;
  • Leader 不均衡超过 20% 并持续 10 分钟→ 失败(ObserverCodeLeaderImbalance)。

observer 的每个样本ObserverSample是"同一轮次的三节点投影",只包含低基数事实(healthy、cluster healthy、leader imbalance、lag breaches 计数),不携带任何原始响应、身份或凭据。

四、Task 2:固定组目录准备与 Worker 分配

4.1 组目录准备的幂等性

setup.go 通过GroupSetup使用现有 benchmark 准备 API 创建2,000 个确定性组频道(formalGroupCatalogTotal)与固定成员关系。三大约束:

  • 幂等:同一run_id重复执行是安全的,已完成的 run 直接返回成功;
  • 形状不匹配即失败:已 fence 的 run 若目录指纹(groupSetupFingerprint,对 ID/成员/归属的派生标签做 SHA-256)不同,返回ErrGroupSetupShapeMismatch,且发生在任何目标变更之前;
  • person 频道绝不通过 setup API 预创建:setup 只写组目录(groupChannelType = 2),人员频道只能由后续真实流量自然创建,这为 Task 3 的 meta-create 记账保留了语义纯净性。

组目录由 groups.go 的GroupCatalog描述:wkg-前缀组 ID、小/中/大/超大四档(超大群固定 100,000 成员、固定成员关系、每分钟一次超大群发送),单批次订阅者上限MaxGroupSetupSubscribersPerBatch = 1,000,以贴合下游订阅者 Raft 命令的固定 UID 数边界。

4.2 确定性分配与 fencing

计划要求把全局用户索引与速率权重确定性地切分为恰好三份,无重叠、无间隙,且单一 coordinator generation。实现中:

  • BuildCoordinatorAssignments(cfg, generation)生成CoordinatorAssignment(含WorkerFence:run_id、generation、worker 分段);
  • 快照聚合器CoordinatorSnapshotAggregator拒绝合并来自其他run_id、其他 assignment 或其他 generation 的快照;
  • NewCoordinator硬性要求恰好三个独立 worker(len(options.Workers) != coordinatorWorkerCount直接返回ErrCoordinatorConfig),Coordinator 一次生命周期只能使用一次(used标记),防止 generation 复用。

4.3 全局速率授予(Grant)

Coordinator 在正式流量开始前先下发初始 grant,随后以1 秒 cadence持续授予(coordinatorGrantCadence)。授予校验极其严格:

  • 三个 worker 的速率之和必须等于 Phase 2 的全局 token bucket;
  • grant tick 时间戳容忍平台定时器量化(10 ms),但拒绝延迟、跳过或追赶的 grant tick(CoordinatorGrantFailureTick);
  • grant 投递容忍 250 ms 的运行时间抖动(coordinatorGrantDeliveryTolerance),超过即视为 delivery 失败;
  • 快照聚合要求 histogram bucket schema 兼容;计数器回退、worker 时钟/序号过期、快照数不等于 3、fence 不匹配、聚合溢出分别对应ErrCoordinatorSnapshotRegression/ErrCoordinatorSnapshotStale/ErrCoordinatorSnapshotCount/ErrCoordinatorSnapshotFence/ErrCoordinatorSnapshotOverflow。

任何 worker 在分配后失败,Coordinator 会停止其余 worker 并返回harness_invalid;任何服务进程连续 30 秒不可用,则停止 worker 并返回product_failure。两种运行都不会被恢复(no resume)。

五、Task 3:证明 loaded / 自然缺失 / reheat 的 Channel 生命周期

这是第四阶段最有技术含量的一步:用真实的、非注入式的方式证明产品在"Channel 冷却后能自然回收、收到消息后能无缝重载"。

5.1 有界 lifecycle-candidate lease

lifecycle_proof.go 定义LifecycleCandidate:一条瞬时、有界的证明租约,包含规范 person 频道身份、物理 Slot 分配(HashSlot/SlotID)、初始序号(InitialSequence)、静默窗口界限(QuietNotBefore/QuietDeadline)与确定性 reheat 截止(ReheatAt)。关键设计:candidate 是瞬时的,绝不原样进入快照或报告(ChannelID被刻意排除在所有聚合证据类型之外)。

5.2 每十分钟的均衡队列选择

计划要求每 10 分钟选出恰好1,200 个候选 = 12 个逻辑 Slot 组 × 100(实现常量lifecycleCohortSize = 1_200、lifecyclePerSlot = 100)。选择偏好:

  1. 优先选择已观察 loaded的 revisit 计划;
  2. 这些频道接下来超过产品自然的 5 分钟 idle eviction 间隔不会收到消息(lifecycleNaturalQuiet = 5 * time.Minute);
  3. 随后确定性 reheat。

重复频道或某个 Slot 队列供应不足 →harness_invalid。

5.3 全节点三态转换状态机

每个候选必须完整经历以下状态机(fake 显式探针响应驱动):

loaded on all three replicas with one leader and monotonic LEO/HW -> naturally absent from all three nodes without eviction API calls -> real SEND reheat -> loaded on all three replicas with sequence continuing above initial sequence

任何以下情况都会使整个 lifecycle 队列失败,并以闭合的LifecycleProductFailureReason词汇归类:error、closing、卡在 loaded 超过有界静默截止、部分副本 reheat(partial reheat)、序号重置(sequence reset)、意外重载等(完整 11 类原因见LifecycleProductFailureCounters)。

特别值得注意的延迟分类规则:cold/reheat SENDACK 延迟只有在同一候选已在三个节点上证明 absent 之后才进入 cold 直方图;未能证明缺失的回归会话不进入 cold 直方图,避免"预热会话"污染冷启动延迟数据。

5.4 异步探针轮询

  • 显式探针按批发出,每批 ≤ 1,200 个身份(lifecycleMaxProbeBatch),并行度上限 32(lifecycleMaxProbeParallel),轮询全部三个服务节点;
  • 探针流量不得计入 Channel 活动,不得延长 eviction;
  • 探针延迟与传输错误单独记账,不归入产品生命周期失败(避免探测开销污染判定)。

5.5 权威元数据创建计数对账

在每次 checkpoint,实现会计算"确定性 person edges + 已准备组目录"对应的期望唯一频道创建数,并与三节点wukongim_channelv2_meta_created_total{result="created"}之和核对:

  • reheated 候选对期望唯一创建数的贡献为 0(重载不得重建元数据);
  • 并发竞争失败者(concurrent losers)可以增加already_existing,但不得增加created。

这一对账用聚合计数证明了"reheat 没有重建元数据",且无需引入 channel-ID 维度的指标标签。

六、Task 4:正确性、延迟、资源与集群阈值判定

判定体系集中在 verdict.go,由VerdictEvaluator将"有界滚动证据"归约为一个冻结结果。

6.1 正确性判定

任何已证实的消息丢失、重复、损坏或序号回退立即失败。TerminalSends与 Channel 激活拒绝必须为零(默认阈值即 0)。失败率采用精确有理数比较(rationalViolates用 128 位乘法避免浮点舍入):

  • 整体运行首试失败率:默认< 1/10,000(OverallFirstAttemptFailure,运算符<);
  • 每个一分钟窗口首试失败率:默认≤ 1/1,000(AnyMinuteFirstAttemptFailure,运算符<=)。

worker 队列饱和或 observer 轮询间隙计数 > 0 →harness_invalid(VerdictCauseQueueSaturation/VerdictCauseObserverGap)。

6.2 延迟窗口判定

前两小时 warmup 之后,按五分钟滚动窗口(SustainedBreachWindow = 5 * time.Minute)执行三档延迟上限:

操作类p99p99.9
Hot SENDACK400 ms1 s
Cold/reheat SENDACK2 s5 s
全量会话同步1 s3 s
  • 任一操作超过10 秒记为 anomaly 样本(SingleAnomaly);
  • 阈值破坏持续满 5 分钟即失败;更短的破坏只记录为 warning/evidence,不改变判定。

实现细节上,VerdictEvaluator用CounterWindow做五分钟窗口内的AboveP99/Count有理比聚合,并在 warmup 边界保留"第一个跨越边界的累积 cut 只作基线、不进入实测证据"的语义,保证预热期延迟不会污染实测数据。同时,延迟破坏还支持归因(attribution):若破坏由基础设施饱和引起,最终判定降级为passed_with_capacity_warning而非产品失败;归因证据不足则判insufficient_evidence。

6.3 资源斜率判定

  • 从每小时forced-GC 指标样本出发,计算滚动 6 小时 live-heap 斜率,超过 5% 失败;
  • 计算24 小时 goroutine 斜率,超过 5% 失败;
  • 队列深度/inflight 在突发后必须回到已建立的 warm baseline(burst ended 时若未回落则VerdictCauseQueueRecovery失败);
  • 每个节点独立评估(三个verdictResourceNode槽位),不允许用平均值掩盖某个泄漏节点;
  • 资源样本的 forced-GC 时间必须小时对齐,且拒绝 NaN/Inf/负数/小数 gauge 值。

6.4 闭合分类与优先级

最终判定采用闭合结果集(实现版比计划多出rehearsal_pass、passed_with_capacity_warning、insufficient_evidence三档):

pass / rehearsal_pass / passed_with_capacity_warning product_failure / insufficient_evidence harness_invalid / infrastructure_failure / operator_stop

分类优先级规则与计划完全一致:磁盘低于 5% →infrastructure_failure;服务崩溃或产品阈值 →product_failure;worker/coordinator/observer 饱和 →harness_invalid。第一个 terminal cause 被冻结后不可更改,后续 cleanup 错误(worker stop / snapshot / observer)以独立的RecordCleanupError环形缓冲附加,不影响主判定。

6.5 有界滚动 reducer

window.go 提供两类内存有界的滚动窗口:

  • CounterWindow:保留固定容量内的精确有理数增量(一分钟失败率窗口容量 16、五分钟延迟窗口 64 样本),已过期条目可被覆盖,未过期条目绝不覆盖;
  • GaugeWindow:保留最新样本与精确跨度前驱,用于 6 小时/24 小时斜率端点计算。

这保证了 72 小时长运行不会无限保留原始样本。

七、Task 5:连续 Checkpoint 与脱敏报告

7.1 连续运行的 checkpoint 语义

计划强调:两小时 shakeout 是独立的 run profile(实现RehearsalConfig,证据主张为rehearsal);正式运行中,24 小时 checkpoint 必须原子写入且不停止/不重分配 worker,同一进程与同一 run generation 继续跑向 72 小时最终判定。实现中CheckpointRecorder.CaptureAndWrite只消费快照与证据,没有任何 worker 生命周期或流量控制能力,输出失败可对同一快照 cut 重试。

7.2 版本化的 JSON / Markdown 输出

report.go 定义的Report契约包含:配置摘要(ConfigDigest)、数据集摘要(DatasetDigest)、拓扑证明、worker generations、时间窗口(start/warmup_end/qualification_at/final_at/end/elapsed)、消息/同步/生命周期/meta-create 记账、延迟/资源/集群证据、terminal 分类与容量结果。所有样本只保留稳定 index + SHA-256 hash(ReportSample{Class, Index, Hash})。三个契约常量被硬编码进每次输出:

  • ReportSchemaVersion = "wukongim/chat-lifecycle-report/v5";
  • ReportThresholdVersion = "wukongim/chat-lifecycle-thresholds/v1"(报告绑定精确阈值语义,默认值演进后结果仍可解释);
  • ReportDesignProfile = "chat-lifecycle-soak/2026-08-04"。

7.3 脱敏与原子写入

  • Redaction 测试:用 bearer token、raw UID、具体 channel ID、标记 payload 播种 fixtures,序列化 JSON 与 Markdown 后断言全部不出现;
  • 原子写入:WriteReportAtomic在目标同目录创建0600权限的临时兄弟文件 → 写入 →fsync→close→rename→ 打开目录句柄再Sync一次。两步 fsync 保证断电/崩溃后不会出现半截报告。

报告写入器绝不把 warning-only 证据变成 pass/fail 变更(ReportWarningCode词汇表与判定解耦),并始终携带精确的 threshold version 与 design profile。

八、Task 6:老化数据容量阶梯

8.1 容量模式准入

capacity.go 规定:容量模式要求已完成 72 小时 checkpoint,且当前服务数据集必须与冻结 checkpoint 一致。实现通过CoordinatorCapacityDatasetProbe在 preflight 之后、任何 setup/worker 变更之前,从每个服务节点直接读取DatasetDigest(包含服务进程 generation,因此重启无法复用冻结的 checkpoint 身份),与CapacityAdmission中的Report比对,不匹配即ErrCapacityAdmission。

8.2 阶梯状态机

  • 起点:2,000 SEND/s(StartRatePerSecond);
  • 每步+25%(StepPercent),持续30 分钟= 10 分钟稳定(Stabilize)+ 20 分钟测量(Measure);
  • 首个失败步之后,以10% 增量(RefinePercent)细化边界区间;
  • 阶梯最多 192 步,快照只保留最近 32 步(maxCapacityRecentSteps);
  • 整体搜索时长上限 8 小时(MaximumDuration)。

CapacityPhase完整枚举:stabilize → measure → rate_pending → recovery → complete → terminal。每步的失败面用CapacityGateFailure位集记录:error rate、latency、queue/inflight、cluster lag、resource、readiness、lifecycle。

8.3 恢复与终局规则

  • 失败/细化边界确定后,降到2,000 SEND/s 恢复 30 分钟,不重启任何服务节点;只有队列/inflight、延迟、错误率、集群 lag、资源压力全部回到接受的 baseline 范围,恢复才算通过;
  • 产品正确性失败仍然立即终止(不受阶梯控制);
  • 容量阈值失败只记录边界并进入有界细化/恢复序列;
  • clean-dataset 容量是可选独立调用,绝不替代老化数据证据(CapacityDatasetClean与CapacityDatasetLiveAged语义分离)。

容量阶梯的快照通过CoordinatorCapacityPeriodicHooks以与 soak 相同的周期性证据 cut 接入报告,最终以ReportCapacityEvidence(attempted/completed/attribution/lower_bound/maximum_passing_rate/first_failing_rate/recovery_passed)落入报告。

九、Task 7:阶段验证

计划收尾要求三类验证,均可直接在当前仓库复现:

# 1. 竞态检测下运行整个包 GOWORK=off go test -race ./internal/bench/chatlifecycle ./internal/bench/target -count=1 # 2. 重复确定性测试:count=20,fixtures 必须逐字节一致 GOWORK=off go test ./internal/bench/chatlifecycle -run 'RelationshipGraph|Assignment|LifecycleProof|Verdict|Capacity' -count=20 # 3. 检查阶段差异:无空白错误、无无关文件被暂存 git diff --check git status --short

十、测试命令速查表

计划内六个任务的测试命令汇总如下(均已落地于internal/bench/chatlifecycle):

阶段命令
Task 1 观测/preflightGOWORK=off go test ./internal/bench/target ./internal/bench/chatlifecycle -run 'Observer|Preflight|Disk|ClusterHealth' -count=1
Task 2 组目录/分配GOWORK=off go test ./internal/bench/chatlifecycle -run 'Setup|Assignment|CoordinatorStart|Grant' -count=1
Task 3 生命周期证明GOWORK=off go test ./internal/bench/chatlifecycle -run 'LifecycleCandidate|LifecycleProof|MetaCreateAccounting' -count=1
Task 4 判定阈值GOWORK=off go test ./internal/bench/chatlifecycle -run 'Verdict|LatencyWindow|ResourceSlope|Classification' -count=1
Task 5 checkpoint/报告GOWORK=off go test ./internal/bench/chatlifecycle -run 'Checkpoint|Report|Redact' -count=1
Task 6 容量阶梯GOWORK=off go test ./internal/bench/chatlifecycle -run 'Capacity|Staircase|Recovery' -count=1

十一、总结:从计划到实现的关键设计原则

对照计划文档与internal/bench/chatlifecycle/实现,可以提炼出四条贯穿始终的设计原则,也是阅读本项目后续阶段(第五阶段容量搜索等)的钥匙:

  1. 身份与证据彻底分离:一切原始身份(UID、channel ID、token、payload)只存在于瞬态探针中;所有持久化证据要么是闭合词汇(cause/code/outcome),要么是 hash/index。这让 72 小时长跑产出的报告天然可归档、可审计、可公开。
  2. 判定即代码,而不是日志:pass/fail 由VerdictEvaluator与Coordinator的闭合状态机冻结,第一个 terminal cause 不可变,后续 cleanup 错误独立记账——判定具有可复现性与确定性。
  3. 一切有界:候选队列、探针批次、滚动窗口、报告 warning/anomaly 数量、容量阶梯步数全部有界,长运行内存恒定。
  4. 真实流量驱动证明:Channel 冷却与重载证明不使用任何 eviction API 注入,而是等待产品自然的 5 分钟 idle eviction 后由真实 SEND reheat,再用 meta-create 计数对账证明"重载未重建元数据"——这是对产品行为最严格的黑盒验证。

如需深入某个子系统的源码细节,建议按以下顺序阅读:先 types.go 与 defaults.go 建立配置心智模型,再依次读 preflight.go、coordinator.go、lifecycle_proof.go、verdict.go,最后以 checkpoint.go 与 report.go 收尾,配合各*_test.go理解每个闭合词汇的判定边界。

  • 即时通讯
  • 后端

【免费下载链接】WuKongIM

More than just IM 不只是即时通讯(IM)

项目地址:https://gitcode.com/gh_mirrors/wu/WuKongIM
点击查看免费下载

相关推荐

上一篇:Flare引擎:自由/开源的动作角色扮演游戏引擎
下一篇:Pylint cell-var-from-loop(W0640):闭包捕获循环变量的晚绑定陷阱与修复实战

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进