工程化、测试与性能 · KNOWLEDGE CHAPTER
K26

发布、协作与可观测

可靠交付是一条可追溯、可止损、可恢复的链:变更意图→确定构建→兼容发布→用户任务→诊断证据。缓存、告警和回滚都依赖准确的身份与版本;速度只有在这条链正确时才有意义。

工程化、测试与性能2 道章节练习9 道主练关联

核心模型

可靠交付是一条可追溯、可止损、可恢复的链:变更意图→确定构建→兼容发布→用户任务→诊断证据。缓存、告警和回滚都依赖准确的身份与版本;速度只有在这条链正确时才有意义。

原理与机制

给构建和预算明确口径

缓存假设声明的输入能确定输出。源码、锁文件、工具版本、配置、影响产物的环境变量和上游任务都应进入正确的指纹,outputs 则决定实际恢复哪些文件;重放日志不证明产物已恢复。受影响任务需沿共享包反向依赖传播。用冷构建与命中缓存的摘要比较,再单独改变输入验证失效。路由预算统计首屏必需资源的去重传递集合,固定压缩算法;绝对上限与相对增长都要检查,零基线应单独报告,不能除零或冒充没有成本。

协作与供应链守住变更意图

Git 三方合并要阅读公共祖先与双方变化,重建业务结果后检查 diff 和测试;删除冲突标记不代表权限逻辑与字段契约一致。rebase 中 ours 通常是已重放的上游一侧,不能按“我的代码”直觉选择。锁文件先确定依赖声明和包管理器,再生成与验证。漏洞修复同样先分析版本、触发入口及生产可达性,再选补丁、隔离或替换;force 跨主版本可能制造新故障。临时风险需负责人、期限和回归证据,并减少安装阶段可接触的秘密。

发布是多版本共存协议

Service Worker 从安装、等待到激活,不代表所有旧页面同时迁移。新资源先准备完整,旧哈希资源保留窗口,草稿和长事务在安全点升级;盲目 skipWaiting 会让旧代码遇到新策略。数据迁移优先增量兼容,破坏性清理延后,回滚版本也必须读得懂已升级数据。缓存还要按授权边界分层:公开壳可以共享,嵌入私有数据的 HTML 不可因此共享;租户、用户、权限和数据版本影响结果,就必须隔离或放弃跨请求复用。

可观测性是受约束的证据采集

发布版本、错误指纹、路由模板与请求关联 ID 连接用户失败和 source map,须用受控错误实际验证还原。日志采用字段允许清单、采样、保留期和访问限制,避免上传令牌、完整表单与私密内容。长会话变慢要重复同一操作脚本,比较回收后的堆基线、DOM、监听器与 CPU;本应释放的对象持续可达才是泄漏证据。缓存也需容量、权重与 TTL,堆稳定但 CPU 增长可能来自重复订阅或积压,不应一概归咎于内存。

用用户任务决定止损

SLI 要明确窗口、分母和成功定义,如完成搜索或提交,不用 HTTP 200 替代。SLO 给出容忍目标,错误预算约束发布风险;灰度前约定失败率、延迟与数据隔离的停止条件。回滚后继续看同一用户指标是否恢复,不能只读部署成功。已经产生的错单或污染缓存需单独定位、核对与修复,技术退回并不会倒转业务时间。低流量短暂无告警也不足以证明可扩大范围。

最小示例

javascript
javascript
function budget(previous, current, maxBytes, maxGrowth) {
  const values = [previous, current, maxBytes, maxGrowth];
  if (values.some(x => !Number.isFinite(x) || x < 0))
    throw new TypeError('invalid budget input');
  const growth = previous === 0 ? null :
    (current - previous) / previous;
  return {
    growth,
    pass: current <= maxBytes &&
      (growth === null || growth <= maxGrowth)
  };
}
console.log(budget(100, 110, 120, 0.1));
console.log(budget(0, 110, 100, 0.1));

示例依次通过、失败;第二次不是无限增长,而是超过绝对预算。输入是假定已按同一压缩口径采集的字节数,函数不能替你找到路由依赖图。CI 对新路由还应要求预算来源,避免缺基线变成逃生口。

核验:Node v24.19.0:等于阈值、增长超限、零基线、绝对超限和NaN拒绝断言通过;不覆盖资源依赖采集或CI集成。

边界与取舍

边界

  • HTML 回滚后,数据库已升版或旧分块已删除,仍可能白屏;恢复设计必须跨缓存、资源与数据。
  • 缓存命中率很高仍可能跨租户泄露;数据隔离的优先级高于命中率。
  • 99.9% 成功率、10万合格请求对应100次失败预算;窗口和分母变了就不能直接比较。

取舍

  • 更细的缓存键减少误复用但降低命中率;缓存范围宁可缩小,也不能遗漏权限维度。
  • 诊断上下文越多越易复现,也越有隐私与存储代价;以最小字段和有期限的采样补证据。

口述示范

我会先证明构建输入、资源版本与权限边界正确,再用用户任务设 SLO 和灰度阈值。故障时保留脱敏证据、止损并回归,最后分别验证技术回滚和业务恢复。

章节练习

练习 1

Monorepo 修改共享包和公开 API 地址后,CI 命中缓存却发布旧地址,如何验证修复?

展开检查点
  • 检查反向依赖、env 哈希与 outputs,不只看缓存日志。
  • 冷构建和缓存恢复比较产物摘要,变更每类输入验证失效。
练习 2

旧 PWA 标签页升级后发生白屏与租户串数据,设计停止条件和恢复证据。

展开检查点
  • 隔离错误缓存,核验用户×租户热缓存交叉用例。
  • 保护草稿,检查 worker/数据库兼容;以任务成功率恢复为准。

参考来源与核验边界

2026-10-04 核验;Turborepo 页面直开为 Markdown,已通过官方检索正文核对输入/输出与确定性条件。SSR 框架缓存默认值随版本变化,本章以实际缓存层与授权键为准。

内容版本:2026-10-04.2 · 题目和来源 ID 保持原样,本站不将面经标签解释为企业官方出题或高频保证。