fix(worker): 限制大图归一化峰值内存
6K 多参考图在 P24 下会并发进入高内存缩放并击穿 2 GiB Worker。新增独立可配置的图片归一化并发,生产默认 2,只约束解码、缩放和重编码阶段,不占用视频上游等待槽;缩放器改为内存稳定的近似双线性实现。\n\n验证:6K 到 6000x2400 转换、信号量串行化、Go 全量测试、gofmt、Kubernetes 客户端 dry-run。
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/easyai/easyai-ai-gateway/apps/api/internal/clients"
|
||||
@@ -195,6 +196,11 @@ func (s *Service) normalizeVideoInputImageSource(ctx context.Context, source str
|
||||
return source, false, original, original, nil
|
||||
}
|
||||
|
||||
release, err := s.acquireImageNormalizationSlot(ctx)
|
||||
if err != nil {
|
||||
return "", false, original, image.Point{}, err
|
||||
}
|
||||
defer release()
|
||||
decoded, _, err := image.Decode(bytes.NewReader(payload))
|
||||
if err != nil {
|
||||
return "", false, original, image.Point{}, fmt.Errorf("图片无法解码")
|
||||
@@ -209,7 +215,7 @@ func (s *Service) normalizeVideoInputImageSource(ctx context.Context, source str
|
||||
contentHeight := max(1, int(math.Round(float64(sourceBounds.Dy())*scale)))
|
||||
left := (target.X - contentWidth) / 2
|
||||
top := (target.Y - contentHeight) / 2
|
||||
draw.CatmullRom.Scale(
|
||||
draw.ApproxBiLinear.Scale(
|
||||
canvas,
|
||||
image.Rect(left, top, left+contentWidth, top+contentHeight),
|
||||
decoded,
|
||||
@@ -228,6 +234,21 @@ func (s *Service) normalizeVideoInputImageSource(ctx context.Context, source str
|
||||
return "data:image/jpeg;base64," + base64.StdEncoding.EncodeToString(output.Bytes()), true, original, target, nil
|
||||
}
|
||||
|
||||
func (s *Service) acquireImageNormalizationSlot(ctx context.Context) (func(), error) {
|
||||
if s.imageNormalizeSlots == nil {
|
||||
return func() {}, nil
|
||||
}
|
||||
select {
|
||||
case s.imageNormalizeSlots <- struct{}{}:
|
||||
var once sync.Once
|
||||
return func() {
|
||||
once.Do(func() { <-s.imageNormalizeSlots })
|
||||
}, nil
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) readVideoInputImageBytes(ctx context.Context, source string) ([]byte, error) {
|
||||
lower := strings.ToLower(source)
|
||||
if strings.HasPrefix(lower, "data:") || (!strings.Contains(source, "://") && !strings.HasPrefix(source, "/")) {
|
||||
|
||||
Reference in New Issue
Block a user