跳转至

视频管线稳定性运维(Temporal)

Admin 种草/剧情试跑已改为 Temporal Workflow 编排,由独立进程 backend-temporal-video 执行 Activity。生图仍走 Redis Stream / FairConsumer,互不影响

业务真相源:仓库内 video/AI视频生成网站-IT交付文档.md

架构要点

能力 实现
编排 Temporal:VideoDramaWorkflow / VideoGrassWorkflow
Worker poetry run backend-temporal-video 或 Deployment temporal-video-worker
剧情流程 Phase1 素材 T2I → Phase2 首帧 I2I → 人工闸门 → 按段 I2V → 有片即 ffmpeg
种草流程 段级 Activity:prepare → 每段 I2I → I2V → merge(无人工闸门)
身份 created_by + operator_phone;C 端预留 user_id/phone;Workflow Memo/SearchAttributes
进度推送 SseHub:GET /api/admin/events/streamvideo.progress / video.retry / video.gate_ready / video.completed / video.failed);轮询降级
失败闭环 Activity 重试耗尽 → finalize_failurefailed + video_dead_letters
上游并发 Redis 信号量 video:i2i / video:i2v / video:ffmpeg(Temporal Worker 内)
API 限流 POST /video/tests 5/min;GET /video/tests/{id} 60/min
剧本 video_scripts(按材质);禁止读本机 Desktop 路径
死信 video_dead_letters;重入队 = 重新 start_workflow

已下线:stream:video / VIDEO_TEST_EXECUTE / Worker 内视频 Stream 消费者 / 旧 Redis 孤儿重入队扫描。

僵尸对账(替代)GET /video/tests 节流触发 / POST /video/tests/reconcile-stale 手动。 规则:pending 默认 >60min、出图/视频/拼接 >180min,且 Temporal Workflow 已死或不存在 → DB 标 failed + 死信; first_frames_ready(人工闸门)永不自动失败;Temporal 不可达时跳过以免误杀。 环境变量:VIDEO_STALE_*(见 Settings)。

本地启动

K3s(推荐)

make k3s-deploy 会部署:

资源 说明
temporal temporalio/auto-setup,库 temporal(挂共享 postgres)
temporal-frontend:7233 gRPC Frontend
temporal-ui Web UI → http://temporal.localhost
temporal-video-worker 视频 Activity Worker

已有集群若 Postgres 早于本次变更建好,Deployment init 会幂等补建 temporal 用户/库。

纯本机(无 K3s)

docker compose -f deploy/k3s/base/temporal/docker-compose.temporal.yaml up -d
make run-backend
make run-storage
make run-backend-temporal-video
# UI: http://localhost:8088

环境变量(backend Settings):

变量 含义 默认
TEMPORAL_HOST Frontend host:port localhost:7233
TEMPORAL_NAMESPACE namespace default
TEMPORAL_TASK_QUEUE Task Queue video-pipeline
TEMPORAL_ENABLED 关闭则试跑启动失败 true
TEMPORAL_MAX_CONCURRENT_ACTIVITIES Worker 同时跑 Activity 数 8
TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASKS Worker 同时处理 Workflow Task 数 40
RUNNINGHUB_API_KEY 视频管线 RH Key (必填)
MESSAGING_VIDEO_SEM_* Redis 信号量(上游硬上限) I2I=8 / I2V=4 / ffmpeg=2

Admin 使用

  1. 剧情:配置 Tab 保存整份剧本 → 测试 Tab 上传产品图 →「生成素材与首帧」→ 审核素材/首帧 → 按段「生成视频」→ 自动拼接成片
  2. 种草:配置提示词组 → 测试 Tab 选组与时长 → 全自动跑完
  3. 进度:前端订阅 GET /api/admin/events/stream;断线时降级轮询 GET /api/admin/video/tests/{id}
  4. 取消:POST /api/admin/video/tests/{id}/cancel
  5. 人工操作:
  6. POST .../materials/{name}/regenerate
  7. POST .../segments/{i}/regenerate(重试首帧)
  8. POST .../segments/{i}/generate-video

Search Attributes(可选)

本地 Temporal 可注册自定义检索属性(未注册时启动自动降级为仅 Memo):

temporal operator search-attribute create --name VideoType --type Keyword
temporal operator search-attribute create --name OperatorId --type Keyword
temporal operator search-attribute create --name OperatorPhone --type Keyword
temporal operator search-attribute create --name UserId --type Keyword
temporal operator search-attribute create --name NotifyPhone --type Keyword
temporal operator search-attribute create --name RunStatus --type Keyword

K8s

  • 清单:deploy/k3s/base/temporal/(Server + UI + video Worker)
  • API / Worker:TEMPORAL_HOST=temporal-frontend:7233(已写入 backend-config-base
  • 不要worker-grass-video / worker-drama-video 当视频管线消费者(它们是 LLM 模型池)
  • ACK:若无法拉 temporalio/*,需先镜像到个人 ACR 再改 Deployment image

排障

现象 排查
试跑一直 pending Temporal 是否可达;Worker 是否在跑;UI 是否有 Workflow
Workflow 启动失败 API 日志 video_workflow_start_failedTEMPORAL_ENABLED
素材/首帧失败 RUNNINGHUB_API_KEY;信号量是否打满;段 error 字段
首帧就绪但不出视频 需人工点「生成视频」(预期行为)

债务

段级 DAG 已由 Temporal 落地。剩余:WebSocket 进度、C 端扣点。见 docs/debt/video-pipeline-stability.md