Files
social-app/docs/plans/2026-02-24-runtime-refactor-plan.md
T
qzl 105cf82d21 fix: 恢复Celery配置 + 修复测试文件
- 恢复 CelerySettings 和相关计算属性
- 修复 celery/app.py 调用 configure_celery_app 参数
- 创建 core/initialization/init_data.py stub
- 删除不完整的 test_auth_supabase_gateway.py
2026-02-24 16:38:30 +08:00

38 KiB
Raw Blame History

运行时架构重构改动清单(Runtime Refactor Plan

日期: 2026-02-24
作者: AI Assistant
状态: Ready for Execution

审批状态流转(Release Readiness

状态 进入条件 退出条件
Draft 计划初稿创建完成 评审材料齐备并发起评审
In Review 架构/平台/后端评审已指派 Owner 阻断项全部关闭
Ready for Execution 阻断项关闭,且满足本节“生效条件” 任一生效条件失效,回退到 In Review
In Execution 按 Phase 开始实施并产生变更记录 全部 Phase 完成并通过验收
Completed 验收、回滚演练、文档归档全部完成

当前状态

  • Ready for Execution

Ready for Execution 生效条件(必须同时满足)

  • AGENTS.md 的 Compose 路径规范已与唯一标准对齐(infra/docker/docker-compose.yml),且校验命令通过。
  • runtime-bootstrap-gate 已写入技术防绕过实施项(CI 依赖、统一执行器、自动检测)。
  • 发布门禁、回滚演练、路由验收硬门槛已在计划内形成闭环,且命令可直接执行。

1. 标题与目的

1.1 重构目标

  • 将长驻进程启动方式从 infra/scripts/*.py 包装脚本,迁移为编排层直接执行可观测命令(uvicorn/gunicorn/celery)。
  • 将迁移/初始化从“混合入口脚本”改为 one-shot job(独立 CLI 命令 + Compose 一次性服务)。
  • 配置策略从 SOCIAL_RUNTIME__ENVIRONMENT 分支控制,迁移为显式参数控制(web/worker 各自配置键)。
  • Celery 从父进程拉多队列(worker.py 内部 Popen)改为按任务类型分组的独立 worker 服务。

1.2 非目标

  • 不改动业务接口、领域逻辑、数据库 schema、Auth 流程。
  • 不新增消息中间件类型(仍使用 Redis 作为 Celery broker/backend)。
  • 不引入新的部署平台(仅调整当前 Docker Compose 运行路径)。

1.3 约束

  • 仅调整运行时与运维启动路径,保持 API 行为兼容。
  • 保持 backend/src/core/config/settings.py 作为唯一环境变量入口。
  • 不在后端运行时代码中新增 os.environ 直读。
  • 迁移期间允许“双轨短期兼容”,legacy 脚本至少保留一个发布周期(定义为一个正式版本迭代窗口)。
  • legacy 脚本删除作为独立里程碑执行,不与入口切换同批发布。

1.4 验收标准

  • 发布门禁:init-job bootstrap 成功(exit code=0)是 web/worker 启动前置条件,未通过禁止发布。
  • 发布门禁唯一入口:本地与 CI 统一执行 runtime-bootstrap-gate,禁止任何绕过 gate 的 up web/worker-*
  • Compose 可直接拉起 web 与分组 worker(至少 critical/default/bulk 三组),且均通过健康/存活检查。
  • SOCIAL_RUNTIME__ENVIRONMENT 不再决定 web 入口类型(gunicorn/uvicorn 由显式开关控制)。
  • 新旧配置并存期遵循“新键优先、旧键告警、版本截止”规则(见第 6 节)。

1.4.1 可测门槛(必须全部满足)

执行上下文约束:所有 Python 命令统一在仓库根目录执行,并显式携带 PYTHONPATH=backend/src;禁止切换为 cd backend 写法。

类别 必跑命令/检查 通过门槛
发布门禁 docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap exit code = 0
启动验证(强制经 gate make runtime-bootstrap-gate && docker compose --env-file .env -f infra/docker/docker-compose.yml ps 两条命令 exit code = 0,且 psweb/worker-critical/worker-default/worker-bulk/redis/db 均为 Up
健康检查 curl -fsS http://127.0.0.1:8000/health exit code = 0
Unit 测试 PYTHONPATH=backend/src uv run pytest backend/tests/unit/test_process_settings.py backend/tests/unit/core/runtime/test_cli.py -q exit code = 0
Integration 测试 PYTHONPATH=backend/src uv run pytest backend/tests/integration -q exit code = 0
E2E 最小链路 PYTHONPATH=backend/src uv run pytest backend/tests/e2e/test_infra_health_e2e.py -q exit code = 0
覆盖率门槛 PYTHONPATH=backend/src uv run pytest backend/tests/unit backend/tests/integration --cov=backend/src --cov-report=term-missing --cov-fail-under=80 覆盖率 >= 80%exit code = 0

1.4.2 Gate 与命令使用边界(消除绕过歧义)

命令类型 允许命令 使用场景 约束
发布/上线(唯一入口) make runtime-bootstrap-gate(内部固定执行 init-job bootstrap -> up web/worker-* 本地发布、CI、手工发布、验收 必须使用;禁止在 gate 之外直接执行 up web/worker-*
演练/排障(非发布) docker compose ... up -d web worker-critical worker-default worker-bulk redis dbdocker compose ... logs ...docker compose ... ps 故障复现、回滚演练、压测、本地调试 必须在 runbook 标注为“演练/排障命令”;不得作为发布放行依据

判定规则:任何“发布成功”结论都必须包含 runtime-bootstrap-gate 成功记录;仅执行直接 up web/worker-* 的记录一律判定为不合规。

1.4.3 路由验收硬门槛(必须满足)

类别 必跑命令/检查 通过门槛
路由用例(critical PYTHONPATH=backend/src uv run pytest backend/tests/integration/test_celery_routing.py::test_route_critical_task_to_critical_queue -q exit code = 0,断言命中 critical 队列
路由用例(default PYTHONPATH=backend/src uv run pytest backend/tests/integration/test_celery_routing.py::test_route_default_task_to_default_queue -q exit code = 0,断言命中 default 队列
路由用例(unknown -> default + 告警) PYTHONPATH=backend/src uv run pytest backend/tests/integration/test_celery_routing.py::test_route_unknown_task_to_default_with_warning -q exit code = 0,断言未知任务落到 default 且产生日志告警
路由验收判定 PYTHONPATH=backend/src uv run pytest backend/tests/integration/test_celery_routing.py::test_route_critical_task_to_critical_queue backend/tests/integration/test_celery_routing.py::test_route_default_task_to_default_queue backend/tests/integration/test_celery_routing.py::test_route_unknown_task_to_default_with_warning -q 三条用例均通过;critical/default 命中正确;unknown 路由不失败且有告警

2. 影响面清单(按文件)

说明:以下为本次重构的目标改动清单,按 Create / Modify / Delete 分类。

2.1 Create

文件路径 用途
backend/src/core/runtime/cli.py one-shot 运行命令入口(migrate/init-data
backend/tests/unit/core/runtime/test_cli.py CLI 参数与流程单测
docs/runtime/runtime-runbook.md 新运行方式(web/worker/job)操作手册

2.2 Modify

文件路径 变更说明
infra/docker/docker-compose.yml 新增/改造 webworker-criticalworker-defaultworker-bulkinit-job 服务及依赖
backend/src/core/config/settings.py 新增显式 web/worker 配置模型,弱化 runtime.environment 分支语义
backend/src/core/celery/app.py 增加队列路由配置与默认队列策略,适配分组 worker
backend/AGENTS.md 在 Phase 0 提前更新运行入口说明(从脚本切换到编排层直启 + one-shot job
.env.example 新增显式启动参数,保留兼容期映射说明
backend/tests/unit/test_process_settings.py 更新设置项断言(显式参数优先)

2.3 DeprecatePhase 0-4

文件路径 处理方式
infra/scripts/web.py 标记 deprecate,保留一个发布周期,不做物理删除
infra/scripts/worker.py 标记 deprecate,保留一个发布周期,不做物理删除
infra/scripts/bootstrap.py 标记 deprecate,保留一个发布周期,不做物理删除
backend/tests/unit/infra/test_web_script.py 标记 deprecate,保留到 Phase 5
backend/tests/unit/infra/test_worker_script.py 标记 deprecate,保留到 Phase 5

2.4 Delete(仅 Phase 5

文件路径 删除原因
infra/scripts/web.py deprecate 窗口结束后物理删除
infra/scripts/worker.py deprecate 窗口结束后物理删除
infra/scripts/bootstrap.py deprecate 窗口结束后物理删除
backend/tests/unit/infra/test_web_script.py 随 legacy 脚本物理删除一并移除
backend/tests/unit/infra/test_worker_script.py 随 legacy 脚本物理删除一并移除

3. 分阶段改造计划

Phase -1:规范对齐阻断项(必须先完成,0.25 天)

变更项(强制前置)

  • 修订根 AGENTS.md 的 Docker Compose 示例路径:从 docker/docker-compose.yml 统一为 infra/docker/docker-compose.yml
  • 明确“单一规范”:仓库所有文档/脚本/CI 示例仅允许 docker compose --env-file .env -f infra/docker/docker-compose.yml ...
  • 将该项设置为 Phase 0 之前的硬门禁;未完成不得进入 runtime 重构实施。

验收检查命令(强制)

rg -n "docker compose .* -f docker/docker-compose.yml" AGENTS.md docs/ infra/ backend/
rg -n "docker compose .* -f infra/docker/docker-compose.yml" AGENTS.md
docker compose --env-file .env -f infra/docker/docker-compose.yml config

通过判定

  • 第一条命令无输出(无旧路径残留)。
  • 第二条命令命中根 AGENTS.md
  • 第三条命令 exit code = 0。

Phase 0:基线冻结与兼容窗口(0.5 天)

变更项

  • docs/runtime/runtime-runbook.md 记录当前启动命令基线与回滚命令。
  • 前移更新 backend/AGENTS.md:将“脚本入口”改为“编排层直启 + one-shot job”。
  • 统一 Compose 文件路径:仅允许 infra/docker/docker-compose.yml,修订范围包括 AGENTS.md、runbook、.env.example、CI 脚本/文档示例。
  • 约定兼容窗口:先引入新入口并灰度验证,再删除脚本入口。

风险点

  • 团队并行开发期间继续调用旧入口,导致“看似可用、实际分叉”。

回滚策略

  • 仅文档与约定变更,回滚为恢复旧 runbook 即可。

验证命令

docker compose --env-file .env -f infra/docker/docker-compose.yml config
PYTHONPATH=backend/src uv run pytest backend/tests/unit/test_process_settings.py -q

验收方式

  • 文档闭环(量化):rg -n "docker compose .* -f docker/docker-compose.yml" AGENTS.md docs/ infra/ backend/ 无输出,且 rg -n "docker compose .* --env-file .env -f infra/docker/docker-compose.yml" AGENTS.md backend/AGENTS.md docs/runtime/runtime-runbook.md .env.example 命中 >= 4。
  • 规范闭环(量化):rg -n "runtime-bootstrap-gate|init-job bootstrap.*前置|禁止.*up web/worker" backend/AGENTS.md docs/runtime/runtime-runbook.md 命中 >= 2,且命中内容覆盖“前置 + 禁绕过”两类语义。

Phase 1:Web 进程直连编排层(1 天)

变更项

  • infra/docker/docker-compose.yml 新增/调整 web 服务:
    • command 直接执行 uv run uvicorn app:app ...dev)或 uv run gunicorn app:app ...prod-like)。
    • working_dir 指向 backend/PYTHONPATH=/app/backend/src(按容器挂载实际路径)。
  • backend/src/core/config/settings.py 新增显式键(示例):
    • SOCIAL_WEB__SERVER=uvicorn|gunicorn
    • SOCIAL_WEB__HOSTSOCIAL_WEB__PORT
    • SOCIAL_WEB__RELOAD
    • SOCIAL_WEB__GUNICORN__WORKERS
  • 去除“仅 prod 走 gunicorn”的硬编码分支依赖。

风险点

  • working_dir/PYTHONPATH 不一致导致 app 模块加载失败。
  • gunicorn 与 uvicorn 参数映射不一致,造成性能/稳定性偏差。

回滚策略

  • 保留 web-legacy profile(临时)可切回 uv run python infra/scripts/web.py
  • 回滚 settings.py 新字段,恢复 app+gunicorn+runtime.environment 逻辑。

Legacy 回滚资产(硬前置)

  • 落地 legacy profile 资产:bootstrap-legacyweb-legacyworker-legacy 三个服务必须可启动且命令固定。
  • docs/runtime/runtime-runbook.md 固化 legacy 回滚步骤、期望结果、故障排查项。
  • 产出并归档一次演练记录(时间、执行人、命令、日志路径、结果、问题单链接)。

Phase 1 DoD(新增硬门槛)

  • web 新入口通过第 1.4.1 的发布门禁与健康检查。
  • legacy profile 资产已落地并可执行:docker compose --env-file .env -f infra/docker/docker-compose.yml --profile legacy config 返回 0。
  • 必须完成一次第 14 节回滚演练并留档;未留档不得进入 Phase 2。

验证命令(第 2-4 条仅用于演练/排障,非发布放行)

docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d web redis db
docker compose --env-file .env -f infra/docker/docker-compose.yml logs web --tail=200
curl -fsS http://127.0.0.1:8000/health

发布门禁

  • init-job bootstrap 非 0 退出码,禁止启动 web 并阻断发布流程。

Phase 2:迁移/初始化 one-shot job 化(1 天)

变更项

  • 创建 backend/src/core/runtime/cli.py,提供子命令:
    • migrate(执行 alembic upgrade head
    • init-data(调用 core.initialization.init_data.initialize_data
    • bootstrap(按顺序执行 migrate + init-data
  • Compose 新增 init-jobdocker compose run --rm init-job bootstrap)。
  • 设定强制门禁:仅允许在 bootstrap 成功后启动 web/worker
  • infra/scripts/bootstrap.py 标记 deprecate 并移出主路径(删除延后至 Phase 5)。

风险点

  • CLI 中同步/异步调用混用导致退出码不准确。
  • 迁移 job 与 web 同时启动出现竞态。

回滚策略

  • 保留 bootstrap-legacy profile(短期)可回退旧脚本。
  • 若 job 失败,恢复旧 bootstrap.py 并维持“初始化先行”的启动前置条件。

验证命令

docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job migrate
docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job init-data
docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap

Phase 3Celery 队列分组与独立服务(1.5 天)

变更项

  • infra/docker/docker-compose.yml 拆分 worker 服务:
    • worker-critical -> --queues=critical
    • worker-default -> --queues=default
    • worker-bulk -> --queues=bulk
  • backend/src/core/config/settings.py 增加队列分组显式配置:
    • SOCIAL_WORKER__GROUPS__CRITICAL__CONCURRENCY
    • 每组支持 pool/time_limit/prefetch_multiplier/max_tasks_per_child
  • backend/src/core/celery/app.py
    • task_default_queue 固定显式默认值(建议 default
    • 增加 task_routes(按任务名前缀或模块路由)
    • 统一异常策略:未知任务路由默认回落 default,并输出结构化告警(event=celery.route.fallback
    • 保持 task_create_missing_queues=False(避免拼写错误静默自动建队列)
  • infra/scripts/worker.py 标记 deprecate(父进程多子 worker 模式退役,删除延后至 Phase 5)。

风险点

  • 无任务路由策略时任务可能全部落到默认队列,造成优先级失效。
  • 队列切分后并发参数不当,导致 CPU 抖动或长尾任务阻塞。
  • 缺少统一指标阈值会导致“已拆分但不可观测”。

回滚策略

  • 暂保留 worker-legacy profile,以单 worker 多队列方式兜底。
  • 发现路由异常时,临时将 task_routes 回退为全量默认队列。

验证命令(仅演练/排障,发布必须走 make runtime-bootstrap-gate

docker compose --env-file .env -f infra/docker/docker-compose.yml up -d worker-critical worker-default worker-bulk redis
docker compose --env-file .env -f infra/docker/docker-compose.yml ps
docker compose --env-file .env -f infra/docker/docker-compose.yml logs worker-critical --tail=120
docker compose --env-file .env -f infra/docker/docker-compose.yml logs worker-default --tail=120
docker compose --env-file .env -f infra/docker/docker-compose.yml logs worker-bulk --tail=120

压测与回归要求

  • 必须先完成第 15 节并发基线压测,再冻结 SOCIAL_WORKER__GROUPS__* 默认值。

Phase 4:收口与发布门禁固化(0.5 天)

变更项

  • 固化不可绕过门禁:init-job bootstrap 作为 CI 必经 jobruntime-bootstrap-gate),deploy job 必须 needs: [runtime-bootstrap-gate],gate 失败即终止流水线并禁止后续 web/worker 启动与发布步骤。
  • 发布脚本与手工发布流程必须先显式执行 docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap,不得依赖 one-shot depends_on 语义来隐式放行。
  • 新增本地统一执行器:infra/scripts/runtime-bootstrap-gate.shmake runtime-bootstrap-gate(仅封装执行顺序,不改变主入口策略)。
  • docs/runtime/runtime-runbook.md 新增“绕过风险”章节:直接执行 up web/worker-* 的风险、排障影响、审计追踪缺失。
  • 新增 CI 自动检测绕过检查:若在 gate 之外检测到直接 up web/worker-*,流水线失败。
  • 更新 runbook、.env.example 与 CI 指南,确保新入口一致。
  • 补充容器化 smoke 流程到 CI,覆盖 worker-critical/default/bulk 三组。

runtime-bootstrap-gate 唯一执行入口(本地/CI共用)

bash -euo pipefail -c '
docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d web worker-critical worker-default worker-bulk redis db
'
  • 以上模板是唯一允许的串行入口:第一条命令非 0 时 shell 立即退出,第二条 up web/worker-* 不得执行。
  • 本地手工执行、发布脚本、CI stage 均必须复用同一模板(stage 名称固定 runtime-bootstrap-gate)。

技术防绕过校验命令(强制)

rg -n "runtime-bootstrap-gate" .github/workflows
rg -n "needs:\s*\[?runtime-bootstrap-gate\]?" .github/workflows
rg -n "docker compose .*up -d .*\b(web|worker-critical|worker-default|worker-bulk)\b" .github/workflows
rg -n "runtime-bootstrap-gate" Makefile infra/scripts docs/runtime/runtime-runbook.md

判定规则:

  • deploy 相关 job 必须显式依赖 runtime-bootstrap-gate
  • 直接 up web/worker-* 仅允许出现在 gate 执行器(脚本或 Make target)中;若出现在其他 CI job,判定为绕过并阻断。

风险点

  • 文档未同步导致新成员仍按旧命令启动。

回滚策略

  • 若发布窗口紧,维持 legacy 脚本 deprecate 状态并延后删除。

验证命令(第 4-6 条仅演练/排障;发布放行看 gate 记录)

PYTHONPATH=backend/src uv run pytest backend/tests/unit -q
PYTHONPATH=backend/src uv run pytest backend/tests/integration -q
PYTHONPATH=backend/src uv run pytest backend/tests/e2e/test_infra_health_e2e.py -q
docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d web worker-critical worker-default worker-bulk redis db
curl -fsS http://127.0.0.1:8000/health

Phase 5:legacy 删除里程碑(独立发布周期后,0.5 天)

触发条件

  • 新入口已稳定运行至少一个发布周期。
  • 第 14 节回滚演练最近一次结果为通过。

变更项

  • 删除 infra/scripts/web.pyinfra/scripts/worker.pyinfra/scripts/bootstrap.py
  • 删除 backend/tests/unit/infra/test_web_script.pybackend/tests/unit/infra/test_worker_script.py
  • 清理文档中所有 legacy 命令。

回滚策略

  • 若删除后发现阻塞,可从发布标签恢复 legacy 脚本并回滚到上一版本镜像。

验证命令

PYTHONPATH=backend/src uv run pytest backend/tests/unit backend/tests/integration -q
docker compose --env-file .env -f infra/docker/docker-compose.yml config

4. 详细改动清单(Checklist,按优先级)

  • P0-1:新增 runtime CLI one-shot 命令入口
    DoDPYTHONPATH=backend/src uv run python -m core.runtime.cli migrate|init-data|bootstrap 均返回正确 exit codeinit-data 调用 initialize_data()
    预计影响:替换 bootstrap.py,降低混合脚本复杂度。

  • P0-0:根 AGENTS Compose 路径规范修订(强制前置)
    DoD:根 AGENTS.md 已统一为 infra/docker/docker-compose.yml;全仓无 docker/docker-compose.yml 启动示例残留;docker compose ... config 校验通过。
    预计影响:消除规范冲突,避免运行入口歧义。

  • P0-2Compose 新增 init-job 并接入 one-shot 流程
    DoDdocker compose run --rm init-job bootstrap 可重复执行(幂等)且 exit code=0;该步骤失败时禁止启动 web/worker
    预计影响:迁移/初始化路径标准化,便于 CI/CD 执行。

  • P0-3Compose 直启 web,移除对 web.py 依赖
    DoDweb 容器命令不再包含 infra/scripts/web.py;且启动前已通过 init-job bootstrap/health 可用。
    预计影响:减少一层 Python 子进程包装,排障路径更直接。

  • P0-4:前移更新 backend/AGENTS.md 与 Compose 路径统一闭环
    DoDbackend/AGENTS.md 已改为新入口规范;仓库文档/脚本示例统一为 infra/docker/docker-compose.yml
    预计影响:降低路径歧义与误启动概率。

  • P1-1:显式 web 配置键落地(SOCIAL_WEB__*
    DoDSOCIAL_RUNTIME__ENVIRONMENT 修改不再影响 web server 选型;选型由 SOCIAL_WEB__SERVER 控制。
    预计影响:配置可预测性提升,环境分支耦合降低。

  • P1-2worker 拆分为 critical/default/bulk 独立服务
    DoDCompose 中存在 3 个 worker 服务,均只消费各自队列且日志区分明确。
    预计影响:任务隔离增强,避免高耗时任务拖慢关键任务。

  • P1-3:Celery 路由显式化并禁用自动建队列
    DoDtask_routes 生效,未知任务默认回落 default 且输出 celery.route.fallback 告警,task_create_missing_queues=False 仍生效。
    预计影响:线上路由错误可提前暴露,运行风险可控。

  • P2-1:删除 legacy 脚本与脚本单测
    DoD:该项仅在 Phase 5(独立里程碑)执行;满足“保留一个发布周期 + 回滚演练通过”后才可移除。
    预计影响:技术债下降,入口唯一化。

  • P2-2:更新文档与 env 模板
    DoDbackend/AGENTS.md.env.exampledocs/runtime/runtime-runbook.md 三处命令一致。
    预计影响:降低 onboarding 成本与误操作概率。

5. 队列拆分策略

5.1 推荐分组

  • critical:用户同步感知任务(验证码发送、鉴权后置关键动作),目标低延迟。
  • default:常规异步任务(中等耗时,可容忍轻微排队)。
  • bulk:批处理/重计算/可延迟任务(高耗时、吞吐优先)。

5.2 何时需要“一队列一服务”

  • 单任务类型 P95 执行时长显著高于其他任务(>3x)。
  • 任务资源模型明显不同(CPU 密集 vs IO 密集)。
  • 任务失败重试会产生级联影响,需要隔离故障域。
  • 业务优先级强约束(SLA 严格,不能被普通任务占满并发)。

5.3 建议默认并发(起步值)

  • critical: concurrency=2~4, prefetch_multiplier=1
  • default: concurrency=2
  • bulk: concurrency=1~2, max_tasks_per_child 较小以抑制内存膨胀

6. 配置迁移表(旧 -> 新)

旧配置 新配置 迁移说明
SOCIAL_RUNTIME__ENVIRONMENT=prod + SOCIAL_GUNICORN__ENABLED_IN_PROD=true SOCIAL_WEB__SERVER=gunicorn server 选型不再依赖 environment 分支
SOCIAL_APP__HOST SOCIAL_WEB__HOST web 显式命名,避免与业务 app 配置混淆
SOCIAL_APP__PORT SOCIAL_WEB__PORT 同上
SOCIAL_APP__RELOAD SOCIAL_WEB__RELOAD reload 仅用于开发态 web 进程
SOCIAL_GUNICORN__WORKERS SOCIAL_WEB__GUNICORN__WORKERS 参数归并到 web 维度
SOCIAL_WORKER__ENABLED_QUEUES=[...] Compose 服务拆分(worker-critical/default/bulk+ SOCIAL_WORKER__GROUPS__* 去掉父进程多队列拉起模式
infra/scripts/bootstrap.py --migrate/--init-data PYTHONPATH=backend/src uv run python -m core.runtime.cli migrate/init-data/bootstrap one-shot job 统一命令入口
SOCIAL_RUNTIME__SERVICE_NAME(脚本注入) Compose service 名称 + logging service_name 显式传参 不再依赖脚本注入环境变量

6.1 新旧配置并存规则(强制)

  • 优先级:新配置键(SOCIAL_WEB__*SOCIAL_WORKER__GROUPS__*)优先于旧键;若同时存在,以新键为准。
  • 告警:检测到旧键生效或新旧同设时,启动日志输出 DEPRECATION WARNING(包含键名、替代键、截止版本)。
  • 兼容截止版本:旧键兼容保留至 v0.9,自 v1.0 起移除旧键解析。
  • 冲突处理:若新旧键值冲突,以新键执行并记录一次结构化告警事件(含 service_name 与环境)。

7. 测试策略(最小可执行集)

7.1 Unit

  • 保留并扩展:backend/tests/unit/test_process_settings.py(新配置解析与默认值)。
  • 新增:backend/tests/unit/core/runtime/test_cli.pyCLI 子命令、错误码、调用顺序)。
  • legacy 保留期:backend/tests/unit/infra/test_web_script.pybackend/tests/unit/infra/test_worker_script.py 标记 deprecate,随 Phase 5 删除。

7.2 Integration

  • 新增/调整:验证 Celery 路由配置可将任务落入预期队列(至少 defaultcritical)。
  • 校验 one-shot bootstrap 流程在测试 DB 可重复执行且无副作用异常。

7.3 E2E

  • 保底保留:backend/tests/e2e/test_infra_health_e2e.py
  • 增加最小链路:init-job -> web health -> worker process alive

7.4 容器化 smoke(必须)

说明:此处 up 命令仅用于 smoke 与排障,不可替代 runtime-bootstrap-gate 发布门禁。

docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d web worker-critical worker-default worker-bulk redis db
curl -fsS http://127.0.0.1:8000/health
docker compose --env-file .env -f infra/docker/docker-compose.yml ps

8. 交付物清单

8.1 文档

  • docs/runtime/runtime-runbook.md(新增)
  • backend/AGENTS.md(更新运行入口说明)
  • .env.example(新增显式配置键与迁移注释)

8.2 配置

  • infra/docker/docker-compose.yml(新增 web/worker 分组/init-job 服务)
  • backend/src/core/config/settings.py(新增 web/worker 显式配置结构)
  • backend/src/core/celery/app.py(显式路由与默认队列)

8.3 脚本/代码

  • backend/src/core/runtime/cli.py(新增)
  • infra/scripts/web.pyinfra/scripts/worker.pyinfra/scripts/bootstrap.py 先标记 deprecatePhase 5 删除

8.4 测试

  • 新增 backend/tests/unit/core/runtime/test_cli.py
  • backend/tests/unit/infra/test_web_script.py 随 Phase 5 删除
  • backend/tests/unit/infra/test_worker_script.py 随 Phase 5 删除
  • 更新 backend/tests/unit/test_process_settings.py

9. 主要风险与缓解

风险 影响 概率 缓解
入口切换后容器启动失败(路径/模块解析) Phase 1 保留 legacy profile;先 compose config 再灰度起服务
队列路由配置缺失或漂移导致关键任务降级 统一 unknown->default+告警策略;增加 test_route_unknown_task_to_default_with_warning 并接入告警阈值
迁移 job 与 web 启动竞态 CI 必经 runtime-bootstrap-gate 串行执行,bootstrap 成功后才允许 up web/worker-*
文档与真实命令不一致 Phase 4 强制三处文档一致性检查(AGENTS/runbook/.env.example

10. 预计工作量

阶段 预计耗时
Phase -1 0.25 天
Phase 0 0.5 天
Phase 1 1 天
Phase 2 1 天
Phase 3 1.5 天
Phase 4 0.5 天
Phase 5 0.5 天(独立里程碑)
总计 5.25 天(含独立里程碑)

11. 已决策项(含验收条件 / Owner / 截止版本)

决策项 已决策内容 验收条件 Owner 截止版本
运行门禁固化 init-job bootstrap 为 CI 必经 jobruntime-bootstrap-gate),失败即终止 CI 日志可见 gate job;当 bootstrap 非 0 时流水线终止且不执行 up web/worker-* Platform/Infra v0.9
Celery 路由最小策略 采用任务前缀路由(tasks.critical.* -> critical,其余默认 default)并保留 bulk 显式路由位;未知任务统一回落 default + 结构化告警 integration 用例验证 critical/default/unknown->default;告警可检索 Backend v0.9
Compose 路径统一 全仓命令统一 --env-file .env -f infra/docker/docker-compose.yml AGENTS、runbook、.env.example、CI 命令均一致且无旧路径残留 Platform/Infra v0.9
Gate 防绕过机制 CI deploy 必须依赖 runtime-bootstrap-gate;本地/CI 统一执行器;绕过自动检测阻断 依赖关系可检索、绕过检查命令通过、runbook 已标注绕过风险 Platform/Infra v0.9

12. 标准 CLI 调用规范(本地/容器/CI)

12.1 统一约束

  • docker compose 固定使用:--env-file .env -f infra/docker/docker-compose.yml
  • Python 命令统一在仓库根目录执行,不使用 cd backend
  • PYTHONPATH 统一为:本地与 CI 使用 backend/src;容器内使用 /app/backend/src

12.2 本地开发(host

PYTHONPATH=backend/src uv run python -m core.runtime.cli bootstrap
PYTHONPATH=backend/src uv run uvicorn app:app --app-dir backend/src --host 0.0.0.0 --port 8000 --reload
PYTHONPATH=backend/src uv run celery -A core.celery.app worker --workdir backend/src --queues=default --loglevel=INFO

12.2.1 本地统一门禁(必须)

bash -euo pipefail -c '
docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d web worker-critical worker-default worker-bulk redis db
'

判定规则:bootstrap 非 0 立即终止,且不得执行任何 up web/worker-*

12.3 容器运行(compose

说明:以下用于本地联调/排障;发布流程仍以 runtime-bootstrap-gate 作为唯一放行依据。

docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d web worker-critical worker-default worker-bulk redis db
docker compose --env-file .env -f infra/docker/docker-compose.yml ps

12.4 CI 流程(pipeline

bash -euo pipefail -c '
docker compose --env-file .env -f infra/docker/docker-compose.yml run --rm init-job bootstrap
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d web worker-critical worker-default worker-bulk redis db
'
PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/runtime/test_cli.py backend/tests/unit/test_process_settings.py -q
PYTHONPATH=backend/src uv run pytest backend/tests/integration -q
PYTHONPATH=backend/src uv run pytest backend/tests/e2e/test_infra_health_e2e.py -q

CI 要求:上述 gate step 名称固定为 runtime-bootstrap-gate,不得拆分为两个可独立重试的 step。

13. 队列拆分后的观测与告警基线

指标 目标阈值 告警条件 处置建议
queue_depth{queue=critical} P95 < 20 连续 5 分钟 >= 50 提升 critical 并发或排查阻塞任务
task_latency_seconds{queue=critical} P95 < 3s 连续 10 分钟 P95 >= 8s 检查路由漂移与上游突发
task_latency_seconds{queue=default} P95 < 30s 连续 10 分钟 P95 >= 90s 扩容 default 或拆分热点任务
task_failure_rate{queue=*} < 2% 5 分钟窗口 >= 5% 触发失败任务抽样与回滚评估
worker_process_alive{group=*} 全部存活 任一 group 存活实例 < 1 持续 2 分钟 自动重启并标记发布风险
worker_cpu_usage{group=*} < 80% 连续 10 分钟 >= 90% 下调并发或扩容容器配额

说明:至少落地前 5 个指标;第 6 个为推荐增强项。

14. 回滚演练用例(新入口 -> legacy

14.0 前置资产与留档要求(硬前置)

  • 资产清单:Compose --profile legacy 下必须存在并可执行 bootstrap-legacyweb-legacyworker-legacy
  • 留档位置:docs/runtime/rollback-drills/,文件命名 YYYY-MM-DD-runtime-legacy-drill.md
  • 留档最小字段:版本号、镜像 digest、执行命令、开始/结束时间、关键日志路径、通过判定、遗留问题。
  • 关卡规则:Phase 1 完成后必须执行一次并留档;未留档不得进入 Phase 2/3/4/5。

14.1 演练触发场景

  • init-job bootstrap 成功但 web/worker 启动后出现持续错误率超阈值。
  • 队列延迟超过第 13 节阈值且 30 分钟内无法恢复。

14.2 演练步骤

  1. 记录当前版本号、镜像 digest、配置快照。
  2. 停止新入口服务:docker compose --env-file .env -f infra/docker/docker-compose.yml stop web worker-critical worker-default worker-bulk
  3. 启动 legacy 入口(deprecate profile):docker compose --env-file .env -f infra/docker/docker-compose.yml --profile legacy run --rm bootstrap-legacy && docker compose --env-file .env -f infra/docker/docker-compose.yml --profile legacy up -d web-legacy worker-legacy redis db
  4. 执行健康检查与关键任务回归(必须执行以下命令):
# 健康探测(5 连续成功)
for i in 1 2 3 4 5; do
  curl -fsS http://127.0.0.1:8000/health >/dev/null || exit 1
done

# 关键路由回归(critical/default/unknown fallback
PYTHONPATH=backend/src uv run pytest \
  backend/tests/integration/test_celery_routing.py::test_route_critical_task_to_critical_queue \
  backend/tests/integration/test_celery_routing.py::test_route_default_task_to_default_queue \
  backend/tests/integration/test_celery_routing.py::test_route_unknown_task_to_default_with_warning -q

# 基础链路回归
PYTHONPATH=backend/src uv run pytest backend/tests/e2e/test_infra_health_e2e.py -q

# legacy worker 告警与关键链路日志检索
docker compose --env-file .env -f infra/docker/docker-compose.yml --profile legacy logs worker-legacy --since=10m | rg "critical|celery.route.fallback"
  1. 对比回滚前后 30 分钟指标(错误率、队列深度、延迟)。

14.3 通过判定

  • web-legacyworker-legacy 在 10 分钟内恢复服务。
  • /health 连续 5 次探测通过(上方循环命令 exit code = 0)。
  • 关键回归命令全部通过:三条 routing 集成测试 + test_infra_health_e2e.py 均 exit code = 0。
  • critical 任务链路恢复,失败率回落至 < 2%,且 worker-legacy 日志 10 分钟窗口内至少出现 1 条 critical 命中记录。
  • 演练记录文档已提交到 docs/runtime/rollback-drills/ 且可被 CI/评审引用。

15. Worker 并发基线压测与调参回归

15.1 基线压测

  • 压测对象:worker-critical/default/bulk 三组并发参数(concurrency/prefetch_multiplier/max_tasks_per_child)。
  • 压测数据:至少包含短任务(<1s)、中任务(1~10s)、长任务(>10s)三类。
  • 产出:每组生成吞吐、P95 时延、失败率、CPU/内存曲线基线报告。

15.2 调参流程

  1. 固定流量模型,单次仅调整一个参数。
  2. 每轮调参后运行 30 分钟压测并记录指标。
  3. 若任一关键指标恶化超过 10%,回退上一组参数。
  4. 选择满足 SLA 且资源利用率最优的一组作为默认值。

15.3 回归要求

  • 每次 worker 参数变更必须复跑第 1.4.1 的全部可测门槛。
  • 必跑回归:test_cli.pytest_process_settings.pytest_infra_health_e2e.py
  • 覆盖率不得低于 80%。

16. 文档级 Go 判定(可执行)

判定项 必跑命令 Go 门槛
门禁一致性(禁止绕过) `rg -n "runtime-bootstrap-gate needs:\s*[?runtime-bootstrap-gate]?" .github/workflows && rg -n "docker compose .up -d .\b(web
文档闭环 rg -n "docker compose .* -f docker/docker-compose.yml" AGENTS.md docs/ infra/ backend/ ; rg -n "docker compose .* --env-file .env -f infra/docker/docker-compose.yml" AGENTS.md backend/AGENTS.md docs/runtime/runtime-runbook.md .env.example 前者无输出;后者命中 >= 4
路由策略一致性 PYTHONPATH=backend/src uv run pytest backend/tests/integration/test_celery_routing.py::test_route_critical_task_to_critical_queue backend/tests/integration/test_celery_routing.py::test_route_default_task_to_default_queue backend/tests/integration/test_celery_routing.py::test_route_unknown_task_to_default_with_warning -q 3/3 用例通过,且 unknown 路由回落 default 并有告警
关键任务链路恢复(回滚场景) `for i in 1 2 3 4 5; do curl -fsS http://127.0.0.1:8000/health >/dev/null
质量门槛 PYTHONPATH=backend/src uv run pytest backend/tests/unit backend/tests/integration --cov=backend/src --cov-report=term-missing --cov-fail-under=80 覆盖率 >= 80%exit code = 0

执行规则:以上 5 项全部满足才可判定文档级 Go;任一项不满足即回退 In Review