可靠性与韧性约定:故障模式、回滚与 Runbook 入口。运行细节见 DEVELOP.md。
| 依赖 | 服务于 | 失效表现 | 兜底 |
|---|---|---|---|
PostgreSQL(或 DB_ENGINE 指定库) |
server 全部 | 接口 500 / 启动失败 | 多库适配,迁移可回退 |
| NATS | 采集(Stargazer/Collector)、SSO、分布式消息 | 无数据上报 / 登录同步停 | Worker 先于 Server 起 |
| Celery + Beat | 告警检测、定时任务 | 告警/定时不触发 | 见下方告警闭环 |
| Redis | Stargazer、缓存 | 任务不被消费 | Server/Worker Redis 必须一致 |
| MinIO | 对象存储 | 附件/模型读写失败 | — |
| MLflow | mlops ↔ algorithms | 训练追踪丢失 | — |
alerts 的通知采用三层闭环:
- 重试(应用层)
- DB 追踪(状态可查、可补偿)
- Celery 补偿(漏发兜底)
改动
alerts通知链时,必须从当前代码与测试确认重试、状态追踪和补偿仍然闭合,不以历史函数名判断。
部分服务会向目标服务器下发插件 / 执行作业(node_mgmt sidecar、job_mgmt、nats-executor/ansible-executor、stargazer 采集)。这类操作直接作用于客户机器,第一原则:绝不能致目标主机崩溃、死机或数据丢失。
约束:
- 资源边界:下发/执行有 CPU/内存/磁盘/超时上界,杜绝打满目标机或无上界拉取(参见技术债中多处「无上界 OOM/DoS」)。
- 幂等可回滚:重复下发不产生副作用;安装/变更失败可回退,不留半成品。
- 不可逆操作显式确认:删除、覆盖、重启目标服务等高危动作,先 dry-run / 预检,再受控执行。
- 凭据与传输:下发链路校验 TLS/host key(勿
skip-tls/AutoAddPolicy);凭据不落明文(参见 安全红线)。 - 必有测试:下发路径的资源边界、失败回滚、越权拒绝必须有自动化测试(单测/集成),不可只手验。
改动任何「下发/执行到目标机」的代码,本节即红线;测试要求见 工程质量 §4。
server/support-files/release/startup.sh 会在 batch_init 返回非零时直接退出,因此任何挂入 batch_init、容器 entrypoint 或其他启动钩子的命令,都会事实上成为服务启动硬依赖。新增启动步骤前必须先按以下标准分级:
| 类型 | 判断标准 | 失败策略 |
|---|---|---|
| 关键初始化 | 缺失时服务无法安全提供任何核心能力,继续运行会造成数据损坏、安全边界失效或不可恢复错误 | 允许阻断启动,但须保留原始错误、给出可执行恢复方式并验证回滚 |
| 非关键初始化 | 缓存预热、缓冲流/索引声明、派生资源生成、可选集成同步等;失败后核心进程仍可运行,资源可稍后重建 | 必须 fail-open:记录告警和原始原因,继续启动,并提供重试、周期对账或人工补偿入口 |
分级结论必须写入变更说明,明确“缺失时影响什么核心能力、继续运行是否损坏数据或安全边界”;不得只用“初始化就应尽早失败”把非关键资源宣称为关键。非关键路径的验收必须断言告警包含异常类型与消息,且重试/补偿入口能恢复资源。
禁止项:
- 禁止扩大启动爆炸半径:不得让非关键、可重建资源的外部依赖异常冒泡到启动入口并退出进程。
--continue-on-error不是替代方案;默认生产启动路径本身必须安全。 - 禁止伪幂等:不得仅凭“同名资源 add 失败后 update”宣称幂等。必须识别资源的真实唯一约束,覆盖同名漂移、异名等价资源、subject/端口/路径等全局冲突以及重复执行。
- 禁止只测全新环境:启动或初始化变更不得只验证空环境首次安装;必须验证带持久化状态的存量环境升级和部分初始化状态。
- 禁止用测试锁死错误策略:非关键资源失败的回归测试必须断言服务继续启动且错误可观测,不得把“异常上抛并中止启动”固化为预期行为。
- 禁止吞掉真因:面向用户的提示可以补充排障建议,但日志必须保留底层异常类型、消息和堆栈;关键失败的异常链不得断裂。不得用固定文案替换 subject 冲突、权限拒绝、容量不足或连接失败等不同原因。
启动/初始化变更的最小测试矩阵:
| 场景 | 必须验证 |
|---|---|
| 空环境首次启动 | 资源按预期创建,服务正常启动 |
| 相同配置重复启动 | 无重复副作用,服务正常启动 |
| 存量状态升级 | 同名配置漂移、异名资源占用真实唯一约束时,行为可预测且不误伤存量数据 |
| 外部依赖异常/部分初始化 | 非关键步骤告警并继续启动,原始错误可定位,后续重试或补偿可恢复 |
本红线源于 PR #4220 与 Issue #4229 的升级回归复盘:全新环境修复不能以存量环境启动可用性为代价。
- 破坏性差集操作必须证明所有权与快照完整性:清理、禁用、删除或回收只能作用于有明确所有权且来自完整快照的资源;快照不完整或归属不明时停止破坏性阶段,不得把“当前未看到”解释为“应删除”。
- 破坏性操作必须可预检和恢复:提供 dry-run、作用范围上界、幂等键、逐项结果和回滚/补偿;失败后能够从持久化断点继续,不得留下不可追踪的部分成功。
- 批量外部副作用必须有界并带背压:消息、通知、文件和远程操作使用有界并发,明确队列饱和、超时和部分失败语义;不得无限并发或静默丢弃。
- 跨独立部署服务的破坏性协议演进必须支持混合版本:API、消息和数据 Schema 显式版本化,验证旧生产者/新消费者与新生产者/旧消费者,按兼容顺序分阶段发布并保留可验证回滚。
| 层 | 动作 |
|---|---|
| 代码 | git revert <commit> |
| 数据库 | python manage.py migrate <app> <target_migration> 回退 |
| 运行 | 回滚到上一个可用镜像 tag 重新部署 |
| 前端产物 | pnpm clean && pnpm install && pnpm build 或回退镜像 tag |
| npm 包(webchat) | 按 npm 版本策略撤回/升补 |
高频项摘录:
make dev启动失败 → 核对.env的 DB/NATS/Redis。make test因迁移失败 → 先make migrate,再查server/scripts/check_migrate/。- Stargazer 无任务消费 → Redis/NATS 与 Server/Worker 一致,先起 Worker 再起 Server。
- K8s 采集器无数据 → 检查
secret.env的CLUSTER_NAME/NATS_*与ca.crt。
- 触及异步任务?已确认重试/幂等
- 触及迁移?已验证可回退(
sqlmigrate/ 逆向迁移) - 触及启动脚本/初始化钩子?已完成关键性分级;非关键失败不阻断启动,并覆盖存量升级测试矩阵(见 §2.6)
- 触及外部依赖调用?失败路径保留原始错误上下文;如调用位于启动路径,是否上抛按 §2.6 关键性分级,非关键失败已捕获、告警且不会冒泡至启动入口
- 触及告警/通知?三层闭环完整
- 触及插件/作业下发?资源有边界、失败可回滚、不可逆操作有预检,且有测试(见 §2.5)
- 触及清理/对账?已证明所有权和快照完整性,具备 dry-run、范围上界及断点恢复
- 触及跨服务协议?已验证混合版本、发布顺序和回滚路径
- 触及数据库查询?走 ORM,无原生 SQL(跨
DB_ENGINE方言)