Files
cs-note/hzh/Gen2D/QA.md
T

160 lines
9.0 KiB
Markdown
Raw Normal View History

2026-06-04 09:33:10 +08:00
# Gen2D — Q&A
> 按模块分布编排,贴近实际答辩场景。每个 Answer 已精简适配 PPT 展示。
---
## 一、系统架构(Q1–Q4)
**Q1:Gen2D 的整体架构是什么?**
A:采用经典分层架构,从浏览器请求到外部依赖共六层:Gin HTTP Server → Handler → Service 层(Eino Pipeline)→ 基础设施层(协程池/队列/事件总线)→ 领域模型 → 外部依赖(MySQL/Redis/CDN/AI API)。各层职责清晰、可独立替换。
**Q2:为什么选择异步任务 + SSE 推送的组合?**
A:AI 生成耗时 10~120 秒,如果同步调用会耗尽服务器连接。异步提交让 API 快速返回 taskId,后续通过 SSE 长连接推送进度,客户端可以自由离开并在后台接收更新。
**Q3:系统的依赖注入方式是什么?为什么没有使用 Wire/Fx 等框架?**
A:采用轻量级的 Set*/Init* 函数注入,在 main.go 中约 220 行完成全部注入。项目规模可控,框架级 DI 的复杂度收益比不高。
**Q4:配置管理是如何设计的?**
A:使用 Viper 实现三层级联:环境变量 > YAML 配置文件 > 代码默认值。容器化部署时可通过环境变量覆盖,开发时使用 YAML 集中管理,零配置也可启动运行。
---
## 二、并发控制与协程池(Q5–Q8)
**Q5:协程池的核心参数和默认值是什么?**
A:Worker 数量 = NumCPU × 4,任务队列容量 = 100,单用户最大并发数 = 2。IO 密集型场景推荐 4 倍 CPU 核数。
**Q6:什么是背压保护?Gen2D 为什么选择非阻塞拒绝而不是阻塞等待?**
A:当协程池队列满时立即返回 ErrPoolFull 错误并返回 HTTP 503,而不是等待有空位。因为用户期望快速反馈,且 AI 生成场景中用户可以重新点击提交——这种短暂的操作成本远低于服务器因连接堆积导致的雪崩风险。
**Q7:Per-user 限流的作用和实现机制是什么?**
A:防止单个用户占满整个协程池。实现上在 Submit 时就增加 userActive 计数预留槽位,任务完成后释放。这样即使 channel 还未取出任务,也能保证槽位一致性。
**Q8:协程池如何优雅关闭?**
A:收到 SIGINT/SIGTERM 信号后,先停止接受新任务(consumeCancel),再通过 wg.Wait 等待所有正在执行的 Worker 完成,超时时间为 30 秒。超时则部分任务可能丢失。
---
## 三、任务队列(Q9–Q11)
**Q9:任务队列的可插拔设计是什么意思?**
A:定义了统一的 TaskQueue 接口(Submit/Consume/Close),支持 MemoryQueue 和 RabbitMQQueue 两种实现。通过配置中的 `driver` 字段一行切换,单机开发用内存队列,生产环境用 RabbitMQ。
**Q10:MemoryQueue 和 RabbitMQQueue 的主要区别是什么?**
A:MemoryQueue 零依赖但无持久化和重试,进程重启任务丢失;RabbitMQQueue 消息持久化到磁盘、支持失败重试和手动 ACK,适合多机部署的生产环境。
**Q11:任务消息的结构中包含哪些关键字段?**
A:包含 TaskID、UserID、ProjectID、Input(PipelineInput)、CreatedAt 和 RetryCount。其中 Input 直接嵌入管线输入结构,反序列化后可直接传入;RetryCount 用于判断是否超过最大重试次数。
---
## 四、生成管线(Q12–Q16)
**Q12:生成管线的四个阶段分别是什么?**
A:第一阶段 PromptOptimizer(提示词优化,纯 CPU <1ms),第二阶段 AssetGenerator(AI 出图,IO 密集 10-120s),第三阶段 QualitySupervisor(质量检查 1-5s),第四阶段 FormatAdapter(格式适配/Cut/GIF 1-3s)。
**Q13:质量检测最多重试 3 次的策略依据是什么?**
A:第 1 次失败通常是 LLM 波动或偶发噪声,重试大概率通过;第 2 次失败说明提示词不够精确,重新优化后改善;第 3 次仍失败表示当前参数确实无法生成合格图片。超过 3 次降级到 FormatAdapter——宁可降级不可阻塞。
**Q14:AssetGenerator 的三级回退逻辑是什么?**
A:优先使用任务级参考图进行图生图,其次使用工程级参考图 URL 下载后图生图,最后回退到纯文生图。任意一级失败都尝试下一级,确保任务不阻塞。
**Q15:管线的安全机制有哪些?**
A:包括三个层面——Eino Graph 设置 WithMaxRunSteps(20) 防止无限循环,WorkerPool 设置 context.WithTimeout(10min) 控制任务超时,以及 context.Canceled 支持优雅关闭时取消执行中的管线。
**Q16:管线的全局状态是怎么管理的?**
A:通过 Eino 的 WithGenLocalState 注入 PipelineState 全局状态对象,各节点通过 StatePreHandler / StatePostHandler 读写状态。状态包含原始输入、最终提示词、质检结果、重试次数和路由目标。
---
## 五、精灵图处理(Q17–Q19)
**Q17:精灵图处理管线包含哪几个步骤?**
A:背景移除(白底/绿幕)→ 投影检测分割 → MinFillRatio 过滤空白帧 → trimAlpha 裁剪透明边框 → padToLargest 底部居中对齐 → GIF 预览生成。
**Q18:两阶段投影算法相比传统方法有什么优势?**
A:传统全局投影会因为武器、尾巴、翅膀等突出物被其他行"稀释"导致切割不准。两阶段算法先用全局行投影检测水平间隙,再在每个行段内独立计算列密度——相当于把二维问题拆解为多个一维子问题,避免跨行干扰。
**Q19:GIF Maker 的防鬼影机制如何实现?**
A:设置 DisposalBackground,每帧渲染前清除前一帧的内容。同时设置调色板索引 0 为透明色,LoopCount=0 实现无限循环播放。
---
## 六、SSE 实时推送(Q20–Q22)
**Q20:EventBus 的订阅模式有哪几种?**
A:两种——Subscribe(taskID) 按任务订阅,Buffer 容量 16,用于单任务实时进度;SubscribeAll() 全局订阅,Buffer 容量 64,用于工程级查看所有任务的混合视图,在 Handler 层按 projectID 过滤。
**Q21:为什么 EventBus 的 Publish 使用 non-blocking send?**
A:使用 select default 模式,当消费者 channel 缓冲满时静默丢弃事件。这是为了防止慢消费者拖慢管线执行速度,保证 Pipeline 的处理效率不受 SSE 推送影响。
**Q22:SSE 连接在什么条件下会自动关闭?**
A:两种情况——收到终态事件(completed/failed)时自动关闭;客户端断开连接时通过 c.Request.Context().Done() 触发 Unsubscribe 并退出。
---
## 七、可观测性(Q23–Q25)
**Q23:Gen2D 的可观测性体系覆盖哪些层面?**
A:共 35 个 Prometheus 指标分为六大组——HTTP 层、限流层、任务队列层、协程池层、Pipeline 业务层、基础设施层。配套 3 个 Grafana 仪表盘(Overview/Pipeline/Infrastructure)和 10 条告警规则。
**Q24:使用 FullPath() 而不是实际路径采集 HTTP 指标有什么用意?**
A:使用路由模板 `/api/v1/tasks/:taskId` 而非实际路径 `/api/v1/tasks/abc123`,避免高基数标签导致 Prometheus 内存爆炸。
**Q25:哪些告警是 Critical 级别需要立即处理的?**
A:PipelineSuccessRateLow(成功率低于 90%)、RedisDown(连接池为零)、RabbitMQDisconnected(断连)和 HighErrorRate(5xx 错误率超 5%)。这些表示核心功能或服务健康度出现严重问题。
---
## 八、限流与降级(Q26–Q28)
**Q26:双层限流的设计思路是什么?**
A:全局限流在前先检查系统总体配额(如 24 小时 500 次),通过后检查用户限流(如 24 小时 15 次)。这样可以先防止单一用户耗尽全局资源,再在用户层面做精细控制。
**Q27:为什么限流器选择 Fail-Open 而不是 Fail-Close?**
A:在"偶尔超限"和"完全不可用"之间,优先保可用性。Redis 故障时放行请求,超出配额的用户后续可以通过账单追缴;如果选择 Fail-Close,Redis 故障会导致所有用户都无法使用服务。
**Q28:三级降级链的第一、二、三级分别是什么?**
A:第一级 TaskQueue(持久化排队 + 分布式能力),第二级 WorkerPool(有界并发 + 用户隔离),第三级 Legacy FIFO(零配置串行兜底)。每一级都是前一级功能的超集,降级过程渐进、服务始终可用。
---
## 九、提示词工程(Q29–Q30)
**Q29:标签驱动提示词工程的工作原理是什么?**
A:内置 40+ 预定义标签分为 7 大类别(内容类型、美术风格、色调配色、线条粗细、场景氛围、光照效果、情绪基调),每条标签映射到精确的图像生成指令。系统将这些指令与用户描述、风格约束和技术参数组装为三段式提示词。
**Q30:为什么精灵图的网格布局需要特殊处理?**
A:如果不指定间隙要求,AI 生成的图片往往人物之间几乎没有空隙——人类艺术家为了最大化利用画布这样做,但机器无法从中推断分割边界。强制纯白间隙等于人为制造"裂缝",让投影检测算法可以可靠地分离每帧内容。