视频管线稳定性运维(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/stream(video.progress / video.retry / video.gate_ready / video.completed / video.failed);轮询降级 |
| 失败闭环 | Activity 重试耗尽 → finalize_failure → failed + 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 使用¶
- 剧情:配置 Tab 保存整份剧本 → 测试 Tab 上传产品图 →「生成素材与首帧」→ 审核素材/首帧 → 按段「生成视频」→ 自动拼接成片
- 种草:配置提示词组 → 测试 Tab 选组与时长 → 全自动跑完
- 进度:前端订阅
GET /api/admin/events/stream;断线时降级轮询GET /api/admin/video/tests/{id} - 取消:
POST /api/admin/video/tests/{id}/cancel - 人工操作:
POST .../materials/{name}/regeneratePOST .../segments/{i}/regenerate(重试首帧)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_failed;TEMPORAL_ENABLED |
| 素材/首帧失败 | RUNNINGHUB_API_KEY;信号量是否打满;段 error 字段 |
| 首帧就绪但不出视频 | 需人工点「生成视频」(预期行为) |
债务¶
段级 DAG 已由 Temporal 落地。剩余:WebSocket 进度、C 端扣点。见 docs/debt/video-pipeline-stability.md。