From f14702362f86dcf91b9087d3d495f34a920b0d24 Mon Sep 17 00:00:00 2001 From: Linghong Date: Fri, 10 Jul 2026 08:54:28 +0000 Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E7=BD=B2=E4=BE=A7=E6=8E=A5=E7=BA=BF?= =?UTF-8?q?=E9=98=BF=E9=87=8C=E4=BA=91=E6=8A=A0=E5=9B=BE=E5=87=AD=E8=AF=81?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D=E6=8A=A0=E5=9B=BE=E5=85=9C=E5=BA=95?= =?UTF-8?q?=E9=9D=99=E9=BB=98=E5=A1=8C=E6=88=90=E4=B8=A4=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit aliyun_matting_enabled 默认 true,但 env 模板/校验器从未提供 GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_*,标准部署里 build_matting_client 因缺 key 返回 None,BgFilter 失败直接本地去背,与三级兜底设计口径不符。 - 两份 api-server.env.example 补 matting 段(enabled/endpoint/AccessKey 占位/timeout) - check-api-server-env.mjs 增可选告警:enabled 但缺 AccessKey 时提示兜底层被跳过 - 开发运维文档补记该层需配 AccessKey 才生效 密钥与 OSS/SMS/token 一致,只留空占位由运维填,不写进 provision/deploy 脚本。 Co-Authored-By: Claude Opus 4.8 --- deploy/container/api-server.env.example | 8 ++++++ deploy/env/api-server.env.example | 8 ++++++ ...发运维】本地开发验证与生产运维-2026-05-15.md | 2 +- scripts/check-api-server-env.mjs | 25 +++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/deploy/container/api-server.env.example b/deploy/container/api-server.env.example index 73f13ca29..002bc4990 100644 --- a/deploy/container/api-server.env.example +++ b/deploy/container/api-server.env.example @@ -35,6 +35,14 @@ GENARRATIVE_WALLET_REFUND_OUTBOX_MAX_BYTES=67108864 GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS=180000 GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_FAILURE_THRESHOLD=3 GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_COOLDOWN_SECONDS=300 +# BgFilter 失败后的中间兜底:阿里云通用抠图(SegmentCommonImage)。AccessKey 留空则跳过该层, +# BgFilter 失败直接本地 editor_green_screen 去背;填入后恢复 BgFilter→阿里云→本地三级兜底。 +# AccessKey 也可复用标准 SDK 命名 ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET。 +GENARRATIVE_ALIYUN_MATTING_ENABLED=true +GENARRATIVE_ALIYUN_MATTING_ENDPOINT=imageseg.cn-shanghai.aliyuncs.com +GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_ID= +GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_SECRET= +GENARRATIVE_ALIYUN_MATTING_REQUEST_TIMEOUT_MS=30000 GENARRATIVE_OTEL_ENABLED=true OTEL_SERVICE_NAME=genarrative-api diff --git a/deploy/env/api-server.env.example b/deploy/env/api-server.env.example index 4d3d9dee8..636b111fc 100644 --- a/deploy/env/api-server.env.example +++ b/deploy/env/api-server.env.example @@ -35,6 +35,14 @@ GENARRATIVE_WALLET_REFUND_OUTBOX_MAX_BYTES=67108864 GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS=180000 GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_FAILURE_THRESHOLD=3 GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_COOLDOWN_SECONDS=300 +# BgFilter 失败后的中间兜底:阿里云通用抠图(SegmentCommonImage)。AccessKey 留空则跳过该层, +# BgFilter 失败直接本地 editor_green_screen 去背;填入后恢复 BgFilter→阿里云→本地三级兜底。 +# AccessKey 也可复用标准 SDK 命名 ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET。 +GENARRATIVE_ALIYUN_MATTING_ENABLED=true +GENARRATIVE_ALIYUN_MATTING_ENDPOINT=imageseg.cn-shanghai.aliyuncs.com +GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_ID= +GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_SECRET= +GENARRATIVE_ALIYUN_MATTING_REQUEST_TIMEOUT_MS=30000 GENARRATIVE_OTEL_ENABLED=true OTEL_SERVICE_NAME=genarrative-api OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318 diff --git a/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md b/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md index 438d00d6f..747ce388b 100644 --- a/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md +++ b/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md @@ -61,7 +61,7 @@ Windows 本地如果已在 `%LOCALAPPDATA%\Genarrative\ffmpeg\bin` 安装 FFmpeg 生产 worker 默认 `GENARRATIVE_EXTERNAL_GENERATION_WORKER_LEASE_SECONDS=600`,只覆盖 worker 心跳抖动和短暂断连窗口,不再把 lease 当成完整任务时长;默认 `GENARRATIVE_EXTERNAL_GENERATION_WORKER_JOB_TIMEOUT_SECONDS=900`,角色动画 / 视频类长任务使用 `GENARRATIVE_EXTERNAL_GENERATION_WORKER_LONG_JOB_TIMEOUT_SECONDS=1800`。worker 在单次尝试超过执行预算后会停止当前尝试、写入失败 / 重试状态并释放 worker 槽位;如果 SpacetimeDB 当时不可写,当前租约最多再保留到 lease 过期,之后任务重新变为可领取。生产部署和 provision 脚本会给 `/etc/genarrative/api-server.env` 与 `/etc/genarrative/external-generation-worker.env` 补齐这些变量;已有自定义值不覆盖,只会把历史旧默认 `3600` 迁移为 `600`。 -图片画布角色图、图标素材和 UI 素材提取在绿色 / 蓝色幕布去背景时优先调用 BgFilter;默认 `GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS=180000`,连续失败达到 `GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_FAILURE_THRESHOLD=3` 后熔断 `GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_COOLDOWN_SECONDS=300` 秒。BgFilter 调用失败和熔断期均先走阿里云通用抠图,只有阿里云失败才走本地幕布色去背景兜底。修改这些变量后需要重启对应 `api-server` / worker 进程;排查时先从 worker 启动日志确认 lease 和 job timeout,再看 `editor_bgfilter_request_start`、`editor_bgfilter_fallback_to_aliyun_matting`、`editor_bgfilter_circuit_open_fallback_to_aliyun_matting`,以及阿里云失败后的 `editor_aliyun_matting_fallback_to_local_screen_background_removal` 日志。 +图片画布角色图、图标素材和 UI 素材提取在绿色 / 蓝色幕布去背景时优先调用 BgFilter;默认 `GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS=180000`,连续失败达到 `GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_FAILURE_THRESHOLD=3` 后熔断 `GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_COOLDOWN_SECONDS=300` 秒。BgFilter 调用失败和熔断期均先走阿里云通用抠图,只有阿里云失败才走本地幕布色去背景兜底。阿里云这层默认 `GENARRATIVE_ALIYUN_MATTING_ENABLED=true`,但必须在 `api-server.env` 填入 `GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_ID` / `GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_SECRET`(或标准 SDK 命名 `ALIBABA_CLOUD_ACCESS_KEY_ID` / `ALIBABA_CLOUD_ACCESS_KEY_SECRET`)才会真正启用;AccessKey 缺失时启动日志会打印「阿里云抠图 AccessKey 未配置,跳过抠图客户端初始化」,抠图直接塌成 BgFilter→本地两级,`npm run check:api-server-env` 也会给出对应告警。修改这些变量后需要重启对应 `api-server` / worker 进程;排查时先从 worker 启动日志确认 lease 和 job timeout,再看 `editor_bgfilter_request_start`、`editor_bgfilter_fallback_to_aliyun_matting`、`editor_bgfilter_circuit_open_fallback_to_aliyun_matting`,以及阿里云失败后的 `editor_aliyun_matting_fallback_to_local_screen_background_removal` 日志。 `我的` 页签或排障面板展示队列等待时,只读取 BFF 队列接口:`GET /api/runtime/external-generation/queue-overview` 查看当前用户可见队列概览,`GET /api/runtime/external-generation/jobs/{jobId}` 查看单 job 状态。生成页 / 进度页不承接队列概览,只展示当前玩法业务进度;队列接口只提供等待 / 运行 / 失败 / 完成状态补充,最终草稿、作品和结果页仍要轮询对应玩法 session/detail 接口收敛到 ready 或 failed;不要直接查询 `external_generation_job` private table,也不要把 worker 内部 payload 暴露到前端。 diff --git a/scripts/check-api-server-env.mjs b/scripts/check-api-server-env.mjs index 212523cc0..4b6f87b04 100644 --- a/scripts/check-api-server-env.mjs +++ b/scripts/check-api-server-env.mjs @@ -47,6 +47,31 @@ if (typoKeys.length > 0) { ); } +// 阿里云通用抠图兜底层:默认 enabled=true,但 AccessKey 缺失时会被静默跳过, +// BgFilter 失败直接本地去背(质量下降)。属可选降级项,只告警不阻断部署。 +console.log('[api-server-env] 抠图兜底(阿里云通用抠图)配置检查'); +const mattingEnabled = env.GENARRATIVE_ALIYUN_MATTING_ENABLED !== 'false'; +const mattingKeyPresent = + hasValue(env.GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_ID) || + hasValue(env.ALIBABA_CLOUD_ACCESS_KEY_ID); +const mattingSecretPresent = + hasValue(env.GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_SECRET) || + hasValue(env.ALIBABA_CLOUD_ACCESS_KEY_SECRET); +printStatus( + 'GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_ID', + mattingKeyPresent, +); +printStatus( + 'GENARRATIVE_ALIYUN_MATTING_ACCESS_KEY_SECRET / ALIBABA_CLOUD_ACCESS_KEY_SECRET', + mattingSecretPresent, +); +if (mattingEnabled && !(mattingKeyPresent && mattingSecretPresent)) { + console.warn( + '[api-server-env] 警告:GENARRATIVE_ALIYUN_MATTING_ENABLED 未关闭但缺少 AccessKey,' + + '阿里云抠图兜底层将被跳过,BgFilter 失败后直接本地去背(质量下降)。', + ); +} + if (missing.length > 0) { console.error(`[api-server-env] 缺少:${missing.join(', ')}`); process.exit(1);