发布和运维
本页描述维护流程。生产主机、挂载路径、凭据位置和当前制品指纹应放入受限现场手册,不写入公开文档。仓库模板与生产实际配置必须分别核对。
发布清单
一个发布批次记录:需求范围、各子仓库 SHA、独立 AutoLab SHA、接口包坐标与校验值、工具链及应用镜像 digest、前端制品清单、Nacos 配置差异、迁移文件及校验值、验证证据与回退条件。首页、公共用例、全局提交、监控、输出台账等单独标明,不能全部归为 IDE 的必要修改。
本地审查提交完成后,仍要在获准 push 时逐仓库 pull --rebase;先子仓库后聚合仓库。接口包发布成功且消费者能读取之后,才能继续消费者 CI。GitHub Actions 成功、镜像构建成功与线上切换成功分别验收。
迁移按功能选择
规范 SQL 位于 deploy 的 migrations/online-ide/。路径沿用历史名称,文件覆盖多项功能,不表示必须把它们一次全部上线。
| 文件 | 用途 |
|---|---|
| V20261008__run_task_and_prefix.sql | Run 结果列与任务扩展前缀;保留扩展值 NOT NULL |
| V20261014__contest_run_context_index.sql | 比赛上下文查询索引 |
| V20261014__global_submission_indexes.sql | 全局提交查询索引 |
| V20261014__public_auto_config.sql | 公共用例自动化配置 |
| V20261014__run_request_dedup.sql | Run 幂等请求;用户配额由现有 Redis 预留机制管理 |
| V20261015__shared_output_provenance.sql | 共享输出归属与引用 |
| V20261014__task_output_files.sql | 私有任务输出元数据 |
| V20261015__legacy_output_ledger.sql | 历史输出台账 |
| V20261015__legacy_output_clearance.sql | 历史输出人工核准 |
| V20261014__run_retention.sql | 任务清理审计 |
problem 库执行任务、上下文、全局查询、公共用例与台账迁移;filesys 库执行 task_output_files、shared_output_provenance、legacy_output_clearance。若业务共用一个数据库,仍按依赖和选定功能核对,先建 run_request 再加 retention 索引。执行前检查目标库版本、现有表/索引、原数据兼容、锁表时间、备份和恢复演练。先在独立环境应用选定文件并重跑验证,记录每份结果;不要自动回填或放宽历史 NOT NULL 约束。
纯本地编辑与原正式提交不需要新 schema。默认提交查询显式排除新任务结果列;只有任务详情查询读取该列。共享输出 claim 默认关闭,普通文件服务不因缺少新表而写 claim。需要云端保存、Run、公共用例自动化或清理时,再启用它们的完整依赖集合。
发布顺序
- 核实目标配置与数据快照,完成必要迁移。服务间 token 使用既有配置来源;缺失、错误或重复内部 token 应拒绝。不要在日志中打印 token。
- 发布并验收 server common/interface 包,然后验证 judger 独立消费;不把邻接源码引入 CI。
- 若功能依赖新 sandbox 能力,经原 judging-containers 手动工作流发布工具链,再按原 Dockerfile 构建 judger。在原生 amd64、arm64 上分别验证同一发布 digest 的 CLI、标准 C/C++ 模板、原 seccomp 规则、stdout JSON、stderr 文件及超时回收;不能用关闭 seccomp 的诊断代替验收。规则兼容修复回到 sandbox 生产者,并验证原拒绝边界;不在消费者打补丁或修改协议字段绕过版本差异。
- 按生产原方式准备成套服务 JAR/lib 或既有镜像。现场若挂载宿主机 JAR/lib,仅拉新镜像不会更新应用,需核对实际挂载制品并整体切换匹配版本。
- 先后端、专用消费者,再前端功能开关。Run 用独立队列和 worker,不能让普通 judger 消费自定义任务。默认本地编辑可独立交付。
- 检查普通登录、题目查询、正式提交、评测结果、WebSocket、上传下载和 AutoLab 原流程,再验证新增能力及权限边界。保存前后错误率、队列与消费者情况。
运行检查与排障
先记录容器/进程、启动参数、挂载、网络、端口和配置来源,再排查健康状态、Nacos 注册、RPC、MySQL、Redis、RabbitMQ 与存储。使用只读命令时也避免输出完整环境变量、配置正文或业务数据。
正式提交积压按“API 受理 → 数据库记录 → MQ 发布/队列 → 消费者 → sandbox → 结果写回 → WS”定位。Run 另外核对配额、幂等键、worker claim/fence、超时恢复和私有输出;两条链的指标分别观察。
Run worker 的 /workspace 必须为 root 所有、不可由提交身份写入,且允许执行编译产物;临时文件系统需显式核对 exec,Docker 的默认 tmpfs 可能带 noexec。每个容器使用自己的 workspace,不在互不可见的 PID namespace 之间共享辅助编译租约池。
自定义 validator/checker 沿原模板编译,但使用独占的非 root 辅助身份;编译后清退该身份的全部进程,再复制为新的 root-owned 文件,运行仍用 nobody 和原规则。不要用 root 编译或把受保护目录改成可任意写来修复权限错误。.helper-uids 中未释放的租约表示异常未清理,不能在 worker 运行时删除或直接复用;先停止并确认该 worker 的全部进程已退出,再由操作者准备该容器的新 workspace。最终镜像验收应包含 Linux 权限、辅助编译、私有输出推广及导入完整链。
生产数据和中间件目录不属于 Git 工作区。RabbitMQ 持久化应核对镜像实际数据目录和挂载,不能仅凭存在一个 volume 判断安全。备份必须包含数据库、文件内容与元数据、配置和当前制品清单;恢复演练在隔离环境进行。
回退
先关闭新功能入口并停止新增任务,再按任务状态决定消费者排空或隔离,保持正式队列继续工作。回退使用匹配的前后端、接口包、JAR/lib 和配置集合;仅回退 UI 不撤销已经发出的任务。
新增表/列通常先保留,不能把删除 schema 当作应用回退的自动动作。清理、历史资产认领、评分修复和数据回填各自需要执行范围、dry-run 结果、审计与恢复方案。默认 dry-run 不等于获准执行真实修改。
AI 扩展的原生写入与协作
个人 AI 集合与提取结果不自动获得原生题库管理权限。任务提交时由服务端确定原生写入目标,执行与采纳时重新检查当前原生管理者、课程范围与协作授权。普通用户的个人提取保留为 AI 资源;只有有效的管理者目标才可创建原生题组。撤销角色或协作授权后,旧任务不能沿用过期权限写入。
智能管理模型执行必须复用持久任务、跨进程租约和使用量账本;Web worker 的进程内字典不能作为会话所有权或全局并发的依据。费用未知时保留待对账状态,禁止按零费用结算。管理员确认请求中的 cookie 只用于当前 OJ 调用,不进入持久任务或日志。多 worker、取消恢复和实际管理协议验收通过前,不将该功能列为可交付。
一个管理 turn 可能发出多次模型请求,包括 CLI 内建工具后的续请求。每个实际请求都要在发往提供商之前重新验证本人管理员身份、任务租约、余额与任务/月度预算,并预留费用;输入预留按普通与缓存输入单价的较高者计算。使用真实响应 usage 幂等结算,流式 incomplete/failed 若带完整 usage 也应结算;缺失用量或用量未知的连接中断进入待对账并阻止后续付费请求。不能只在管理员确认工具时检查预算,也不能只依靠整轮结束后的累计计数。