5.3 KiB
5.3 KiB
name, overview, todos
| name | overview | todos | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| model-call-retry | 为抠图(Matting)与分类(Classification)两个模型调用增加可配置的自动重试机制,默认最大重试 3 次;配置项分别加到 MattingModel 与 ClassificationModel 配置段下,并在衣物异步处理流程中接入重试逻辑。 |
|
产品概述
为衣物图片处理流水线中的抠图(Matting)与分类(Classification)两个模型调用增加自动重试能力,降低下游模型服务偶发失败导致的衣物处理失败率。重试次数通过配置文件分别控制,默认最大重试 3 次。
核心功能
- 抠图调用失败时自动重试,默认最大重试 3 次(总尝试 4 次)
- 分类调用失败时自动重试,默认最大重试 3 次(总尝试 4 次)
- 重试次数分别配置在
MattingModel与ClassificationModel两个配置段下,配置缺失或小于等于 0 时兜底为 3 - 全部重试失败后维持现有失败处理:抠图失败回退上传额度并标记失败;分类失败保留已抠图结果(processed_image)并标记失败,便于用户手动补全
- 删除处理中衣物不回退额度的既有防滥用设计保持不变(不做修改)
技术栈
- Go 1.27(使用泛型、
log/slog、context+time.After) - 配置:viper(复用现有
setting.ReadSection读取模式) - 日志:
log/slog(复用现有slog.WarnContext/slog.ErrorContext)
实现方案
总体策略
复用现有配置读取与兜底模式,在配置结构体、配置文件中增加 MaxRetry 字段;在异步处理函数 processImageAsync 中新增一个泛型重试辅助函数 retryCall,包裹抠图与分类两处调用,实现失败自动重试,失败分支逻辑保持不变。
关键设计
- 配置层(最小改动)
pkg/setting/section.go的MattingModelSettingS、ClassificationModelSettingS各新增MaxRetry int字段。configs/config.yaml(实际配置)与configs/config.example.yaml(示例配置)的MattingModel、ClassificationModel段各新增MaxRetry: 3。main.go在读取MattingModel、ClassificationModel后,对MaxRetry <= 0兜底为 3,与现有MaxSizeMB <= 0兜底 20、Model == ""兜底hy4的模式保持一致。
- 重试层(泛型辅助函数)
- 在
internal/service/clothes.go新增retryCall[T any]泛型函数:循环尝试maxRetry+1次;每次失败记录slog.WarnContext;重试间隔使用select+time.After(1s)+ctx.Done(),保证 ctx 到期时提前终止。 - 抠图与分类调用分别用
retryCall包裹,maxRetry分别取global.MattingModelSetting.MaxRetry与global.ClassificationModelSetting.MaxRetry。 fn闭包捕获外部ctx,每次调用内部会重建 multipart body,无需额外重置状态。
- 失败分支保持不变
- 抠图全部重试失败后仍调用
markProcessFailed(标记失败 + 回退上传额度)。 - 分类全部重试失败后仍保留
processed_image并标记ImageProcessFailed(不回退额度,允许用户手动补全)。
关键代码结构
// retryCall 对 fn 进行最多 maxRetry 次额外重试(总尝试 maxRetry+1 次)。
// 重试间隔 1s;ctx 到期则提前终止并返回 ctx.Err()。
func retryCall[T any](ctx context.Context, maxRetry int, name string, fn func() (T, error)) (T, error)
// 调用示例
processedData, err := retryCall(ctx, global.MattingModelSetting.MaxRetry, "matting", func() ([]byte, error) {
return mattingClient.Matting(ctx, imageData)
})
实现注意
- MaxRetry 语义:失败后的额外重试次数,总尝试次数 = MaxRetry + 1;默认 3 即总尝试 4 次。
- 超时预算:异步 ctx 总超时为 3 分钟,单次 HTTP 客户端超时为 120s。
retryCall通过ctx.Done()检查避免超时后继续重试;瞬时失败(连接拒绝、偶发非 200)通常快速返回,3 分钟预算足够。 - 并发限流不受影响:
imageProcessSem信号量在processImageAsync入口已获取,重试发生在同一 goroutine 内,不会放大并发。 - blast radius 控制:仅新增配置字段与重试辅助函数,不修改
DeleteByUUID额度回退逻辑;config.yaml中重复的UserDefaultQuota段为既有问题,本次不处理。
目录结构
zt-closet-backend/
├── pkg/setting/section.go # [MODIFY] MattingModelSettingS、ClassificationModelSettingS 各新增 MaxRetry int 字段
├── configs/config.yaml # [MODIFY] MattingModel、ClassificationModel 段各新增 MaxRetry: 3
├── configs/config.example.yaml # [MODIFY] MattingModel、ClassificationModel 段各新增 MaxRetry: 3
├── main.go # [MODIFY] 读取 MattingModel、ClassificationModel 后对 MaxRetry<=0 兜底为 3
└── internal/service/clothes.go # [MODIFY] 新增 retryCall 泛型辅助函数,抠图/分类调用接入重试