
工具链高峰前的构建防线发版日前后构建系统会同时面对更多提交、更多分支和更多重复任务。平时偶尔出现的缓存失效、依赖下载变慢或 Runner 磁盘不足到高峰期会互相放大任务排队开发者手动重试新的重试又占满执行槽。构建防线要做的是让相同输入得到可复现产物并在资源不够时有序退让。先保证输入可确定一份构建任务至少要固定源码提交、依赖锁文件、工具链版本、目标平台和构建参数。只记录分支名不够因为分支在排队期间仍可能向前移动。容器基础镜像也应使用不可变标识而不是把浮动标签当作确定版本。只有输入明确失败任务才能复现缓存结果也才值得复用。构建脚本不要依赖 Runner 上“刚好存在”的全局工具、用户配置或未声明环境变量。高峰期临时扩容的新节点通常更干净隐藏依赖会在这个时候集中暴露。可以定期用空缓存、全新执行环境跑一次完整构建确认项目离开常驻节点仍能成功。缓存键要覆盖真实影响因素缓存能明显减少重复编译但错误缓存比没有缓存更麻烦。缓存键需要包含真正影响输出的源码、锁文件、编译器版本、目标平台和关键参数。原文的哈希写法可以用来生成内容标识let key blake3::hash(bytes).to_hex().to_string();这里的bytes不能只放源码压缩包。如果 Feature、环境变量或代码生成器版本会改变产物也要进入摘要。缓存条目还应区分可共享和项目私有避免不同租户通过猜测键读取彼此产物。命中缓存后可以抽样校验产物元数据发现缓存污染时按命名空间失效不要清空所有项目的缓存来碰运气。相同提交的重复任务可以合并等待同一个结果但取消语义要明确一个调用者取消不应结束其他人仍需要的共享构建。真正执行失败后等待者收到同一失败原因是否重试由调度策略决定而不是每个客户端立即各跑一遍。队列和执行槽分层控制构建任务消耗的不只有 CPU。链接会占用大量内存拉取依赖占网络生成镜像会迅速增加磁盘使用。调度器应按任务类型设置资源请求把轻量检查和重型构建分开防止少数大任务堵住所有反馈。每个项目与用户还应有并发上限给紧急修复预留少量受控通道但不能让“紧急”成为绕过队列的常态。队列需要显示位置、预计等待和拒绝原因。达到容量上限时及时拒绝新任务比接受后等待很久再超时更容易处理。自动重试只适合节点丢失、临时网络失败等明确的瞬时故障编译错误和测试失败不应重试。依赖仓库不可用时优先使用已校验的本地缓存并明确哪些构建因缺少新依赖无法继续。产物离开构建节点前再验一次构建成功不等于产物可发布。归档前应核对产物与提交的对应关系、目标架构、签名或摘要、测试状态和来源元数据。上传使用临时名称完成后再发布可见索引避免消费者拿到半截文件。构建日志与产物中不得混入令牌、私有仓库凭据或 Runner 的本地路径。高峰演练要覆盖空缓存、缓存服务变慢、依赖仓库不可用、Runner 突然退出、磁盘水位过高和大量重复提交。观察排队时间、任务完成率、缓存命中、下载流量和失败分类停止加压后还要确认队列能下降、临时目录能清理。工具链能扛住高峰不是因为机器足够多而是因为输入确定、重复工作被合并、超量请求能被及时挡住。