fix(#1714): beat 调度文件改 /tmp,修复定时巡检任务从未执行 #1736

Merged
xiaoxia merged 1 commits from fix/beat-schedule-permission-1714 into develop 2026-09-06 14:21:55 +08:00
Owner

背景

PR #1734 部署 staging 验证时发现:worker 容器内 celery beat 进程启动即崩溃,日志:

_gdbm.error: [Errno 13] Permission denied: 'celerybeat-schedule'

根因

  • worker 容器以非 root 用户 celery 运行,工作目录 /app/apps/worker 属 root(755),celery 用户不可写;
  • entrypoint-worker.sh 中 generation worker 内嵌 beat(-B)未指定 --schedule 路径,celery beat 默认在 CWD 创建 celerybeat-schedule shelve 持久化文件 → 权限拒绝 → beat 进程退出;
  • 结果:所有 beat 定时任务(generation 链路清理 + 本次新增的 ingest 孤儿巡检 cleanup-stale-ingest-jobs)从未执行。production 日志确认同样中招(自 #1722 队列隔离部署起)。

注:worker 启动恢复(worker_ready 信号,不依赖 beat)工作正常——staging 实测孤儿 job 02eed0d9 已被自动重置 pending 重派并转码完成。

修复

entrypoint-worker.sh 为内嵌 beat 增加 -s /tmp/celerybeat-schedule

  • /tmp 对 celery 用户可写;
  • beat 调度文件是易失运行时文件,重启重建无影响(错过的巡检由启动恢复 + 下一轮巡检兜底)。

部署后效果

  • beat 正常运行,每 10 分钟巡检:ingest_job processing>60min/pending>90min 转 failed;无 job 关联的 processing asset>120min 标 error;
  • staging 现存 106 条历史僵尸 processing asset 将在部署后首轮巡检标记 error。

测试

  • shell 脚本改动,无 Python 逻辑变更,现有测试不受影响;
  • 部署 staging 后实测 beat 日志无 Permission denied、巡检任务按 600s 周期触发。
## 背景 PR #1734 部署 staging 验证时发现:worker 容器内 celery beat 进程启动即崩溃,日志: ``` _gdbm.error: [Errno 13] Permission denied: 'celerybeat-schedule' ``` ## 根因 - worker 容器以非 root 用户 `celery` 运行,工作目录 `/app/apps/worker` 属 root(755),celery 用户不可写; - entrypoint-worker.sh 中 generation worker 内嵌 beat(`-B`)未指定 `--schedule` 路径,celery beat 默认在 CWD 创建 `celerybeat-schedule` shelve 持久化文件 → 权限拒绝 → beat 进程退出; - 结果:**所有 beat 定时任务(generation 链路清理 + 本次新增的 ingest 孤儿巡检 cleanup-stale-ingest-jobs)从未执行**。production 日志确认同样中招(自 #1722 队列隔离部署起)。 注:worker 启动恢复(worker_ready 信号,不依赖 beat)工作正常——staging 实测孤儿 job 02eed0d9 已被自动重置 pending 重派并转码完成。 ## 修复 entrypoint-worker.sh 为内嵌 beat 增加 `-s /tmp/celerybeat-schedule`: - `/tmp` 对 celery 用户可写; - beat 调度文件是易失运行时文件,重启重建无影响(错过的巡检由启动恢复 + 下一轮巡检兜底)。 ## 部署后效果 - beat 正常运行,每 10 分钟巡检:ingest_job processing>60min/pending>90min 转 failed;无 job 关联的 processing asset>120min 标 error; - staging 现存 106 条历史僵尸 processing asset 将在部署后首轮巡检标记 error。 ## 测试 - shell 脚本改动,无 Python 逻辑变更,现有测试不受影响; - 部署 staging 后实测 beat 日志无 Permission denied、巡检任务按 600s 周期触发。
xiaoxia added 1 commit 2026-09-06 14:14:07 +08:00
fix(#1714): beat 调度文件改用 /tmp 路径,修复 celery 用户无 CWD 写权限导致 beat 崩溃、定时巡检(ingest 孤儿清理)从未执行
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 36s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 36s
AI Code Review / AI Code Review (pull_request) Successful in 49s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 51s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 1m45s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m50s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 2m25s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m50s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 5m20s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 7m24s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 7s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 15s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 5m12s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 10m21s
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 12m29s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 12m47s
dddc1cd081
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:否
  • 阻塞级问题数量:0 个

📊 审查概览

  • 整体评价:通过
  • 建议级问题数量:1 个

🔴 阻塞级问题(必须修复)

💡 改进建议(不阻塞合并)

  1. [infra/docker/entrypoint-worker.sh: 第39行] 调度文件持久化建议
    • 具体内容:将 Celery Beat 调度文件 (-s) 指定在 /tmp 目录下,虽然解决了容器内非 root 用户写入权限的问题,但该目录通常属于临时存储。在容器重启或崩溃后,调度状态(如上次运行时间)会丢失,可能导致周期性任务在重启后立即重复执行。如果对任务执行时间精度要求较高,建议通过 Docker Volume 将该路径挂载到持久化存储中。

良好实践

  • 显式指定 -s 参数是一个良好的实践,避免了 Celery 默认在当前目录(可能不可写)创建文件导致的启动失败,增强了脚本在不同环境下的兼容性。

🤖 由 AI 代码审查机器人自动生成 | 2026-09-06 06:14:58 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:否 - 阻塞级问题数量:0 个 ### 📊 审查概览 - 整体评价:通过 - 建议级问题数量:1 个 ### 🔴 阻塞级问题(必须修复) 无 ### 💡 改进建议(不阻塞合并) 1. **[infra/docker/entrypoint-worker.sh: 第39行] 调度文件持久化建议** - 具体内容:将 Celery Beat 调度文件 (`-s`) 指定在 `/tmp` 目录下,虽然解决了容器内非 root 用户写入权限的问题,但该目录通常属于临时存储。在容器重启或崩溃后,调度状态(如上次运行时间)会丢失,可能导致周期性任务在重启后立即重复执行。如果对任务执行时间精度要求较高,建议通过 Docker Volume 将该路径挂载到持久化存储中。 ### ✅ 良好实践 - 显式指定 `-s` 参数是一个良好的实践,避免了 Celery 默认在当前目录(可能不可写)创建文件导致的启动失败,增强了脚本在不同环境下的兼容性。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-09-06 06:14:58 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->

🚀 预览环境已部署

项目 详情
PR号 #1736
预览链接 https://pr-1736.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1736 | | 预览链接 | [https://pr-1736.preview.xiaoxiajianji.com](https://pr-1736.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia merged commit 873008dde8 into develop 2026-09-06 14:21:55 +08:00

🗑️ 预览环境已清理

PR #1736 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1736 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.