限制 dev 发布目录与 Jenkins 构建暂存的历史堆积
Project CI / AI game creator shell Rust crates (push) Successful in 1m26s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m53s
Project CI / Backend tests (push) Successful in 3m47s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Successful in 1m26s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m53s
Project CI / Backend tests (push) Successful in 3m47s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
- production-api-deploy.sh 新增 --keep-releases(默认 2):发布成功后保留 current 目标与最近 1 个历史 release,只清理同时含 api-server 或 web 标记的旧目录,清理失败只告警、不改变发布结论 - production-api-deploy.sh 新增 prune_old_releases 与参数校验:非整数或小于 1 的 --keep-releases 在任何动作之前失败 - check-production-api-deploy 增加默认值、显式值和非法值三类夹具,并断言非法参数不会提升 release - check-production-ops 增加 release 保留策略与三个部署 Job 暂存清理的合同 - Api Deploy、Web Deploy、Stdb Publish 三个 Jenkinsfile 在部署或发布成功后只保留最近 2 个 build/<version> 暂存,失败时保留暂存便于诊断和重跑 - 内联清理片段避开 Groovy 反斜杠转义,并在 set -euo pipefail 下对空 build 目录安全(if [ -d build ] 守卫加兜底) - 开发运维文档补充 release 与 Jenkins 暂存的保留上限口径 - pitfalls 记录 dev 根盘写满的两处根因(发布与暂存无上限、JNLP 幽灵 agent 刷 syslog)以及 Jenkins 内联 shell 的两个坑
This commit is contained in:
@@ -1,5 +1,22 @@
|
||||
# 踩坑与排障记录
|
||||
|
||||
## 2026-09-29 历史 release 与 Jenkins 构建暂存必须显式设置保留上限
|
||||
|
||||
- **现象**:dev 服务器根盘写满(`/dev/vda2` 47G/50G,可用 960M,99%)。两侧都只写不回收:`Genarrative-Api-Deploy` / `Genarrative-Web-Deploy` / `Genarrative-Stdb-Module-Publish` 三个 Job 工作区的 `build/<n>/` 暂存 9.8G,`/opt/genarrative/releases/` 下 68 个历史发布目录 9.2G;另有 journald 归档 700M 和轮转 syslog 437M。
|
||||
- **原因**:`production-api-deploy.sh` 用 `cp`(不是 `mv`)把 `${SOURCE_DIR}` 拷进 `${RELEASE_ROOT}/${VERSION}`,所以 Jenkins 工作区里的 `build/<version>/` 永远留着;dev 上构建 agent 与发布目标机是同一台机器,同一份产物在盘上存在两份。脚本和 Job 两侧都没有保留上限,按小时级 dev 发布节奏约 1G/天。
|
||||
- **处理**:两侧都补了保留上限。服务端:`production-api-deploy.sh` 新增 `--keep-releases`(默认 `2`),发布成功后保留 `current` 目标与最近 1 个历史 release,只删除同时含 `api-server` 或 `web` 标记的旧目录,清理失败只告警、不改变发布结论。CI 侧:`Genarrative-Api-Deploy` / `Genarrative-Web-Deploy` / `Genarrative-Stdb-Module-Publish` 在各自部署 / 发布步骤成功后只保留最近 2 个 `build/<version>/`,失败时不清理以便诊断和重跑。`npm run check:production-api-deploy` 增加默认值、显式值和非法值三类夹具,`npm run check:production-ops` 增加对应合同。
|
||||
- **不要踩的坑**:直接按 mtime 排序删除会连带删掉发布根目录下不属于发布产物的目录(例如 `dev-mcp-host-*`),必须用 `api-server`/`web` 标记筛选;脚本里的 `mv -T`、`find -printf` 都是 GNU 语义,`npm run check:production-api-deploy` 需要 `sha256sum` 和 `/usr/bin/cp`,Windows 本地跑不了,只在 Linux CI / Linux 检出上有效(本地最低限度用 `bash -n` + `npm run check:production-ops`)。
|
||||
- **写 Jenkins 内联 shell 的两个坑**:① Groovy 会处理 `sh '''…'''` / `sh """…"""` 里的反斜杠转义——`\n` 到 shell 手上会变成真实换行(`Jenkinsfile.production-stdb-module-build` 里必须写 `printf "\\r"` 就是同一件事),所以内联片段要么完全不用 `\`,要么写 `\\`;`"""` 是 GString,shell 变量必须写 `\$name`,而 `'''` 不插值、保持 `${name}`。② `set -euo pipefail` 下 `ls build/*/` 在 glob 不匹配时会因 pipefail 把整个部署步骤判失败(实测:`build/` 为空时清理步骤会把一次成功发布判成失败),必须用 `if [ -d build ]` 守卫 + `|| true` 兜底。
|
||||
- **关联**:`scripts/deploy/production-api-deploy.sh`、`scripts/check-production-api-deploy.mjs`、`scripts/check-production-ops-guardrails.mjs`、`jenkins/Jenkinsfile.production-api-deploy`、`jenkins/Jenkinsfile.production-web-deploy`、`jenkins/Jenkinsfile.production-stdb-module-publish`。
|
||||
|
||||
## 2026-09-29 dev 上的 JNLP inbound agent 是历史残留,会在死端口上无限重连刷爆 syslog
|
||||
|
||||
- **现象**:dev 的 `/var/log/syslog` 约 250MB/天,内容是 `jenkins-inbound-agent-start[pid]` 反复输出指向 `http://127.0.0.1:18080/tcpSlaveAgentListener/` 的 `Connection refused` 完整栈(2.6 天 61 万行,其中 `genarrative-release-deploy-01` 占 53 万行)。
|
||||
- **原因**:`/etc/jenkins-agent/*.env` 里 `JENKINS_URL=http://127.0.0.1:18080/`,而该机只有 station 反向 ssh 提供的 `18085/18086/18087`,没有 `18080`。真实部署通道是 SSH launcher(`java -jar remoting.jar -workDir /root/jenkins-agent-build`,sshd 会话子进程),Jenkins 工作区、`current` 切换和当日 01:18 的发布都由它完成;两个 JNLP 单元从未连上(`release-deploy-01` 的 workdir 自 2026-05-09 起没有任何 workspace)。
|
||||
- **处理**:停止并 disable `jenkins-agent@genarrative-build-01.service` 与 `jenkins-agent@genarrative-release-deploy-01.service`;观测窗口内 `Failed to connect` 新增归零,`genarrative-api` / `spacetimedb` / worker / pingora 保持 active。回滚用 `systemctl enable --now jenkins-agent@<name>.service`。
|
||||
- **不要踩的坑**:`ss -t` 在没有状态过滤时不显示 LISTEN,连接被瞬拒时也抓不到 TCP 连接,不能用它判断 agent 是否在线;要看 `journalctl -u jenkins-agent@<name>`、`ss -tlnp` 的端口和 Jenkins 工作区归属。停 JNLP 单元前先确认控制器 `slaveAgentPort=-1` 且 SSH launcher 仍在跑,避免把唯一通道停掉。
|
||||
- **关联**:`/etc/systemd/system/jenkins-agent@.service`、`/etc/jenkins-agent/*.env`、`scripts/deploy/install-jenkins-inbound-agent.sh`。
|
||||
|
||||
## AGC 版本探测必须显式提供隔离用户目录
|
||||
|
||||
清空子进程环境后缺少 `USERPROFILE/HOME` 会让 npm 依赖 Windows 后备用户查询,部分机器报 `uv_os_homedir` / `ENOMEM`。正常机器探测成功不能证明环境完整,需同时验证子进程环境。版本探测使用临时用户目录和空 npm 配置,详见 [AGC 实施计划](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md) 的“Web 环境版本探测的用户目录隔离”。
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user