perf(queue): 限制大媒体任务内存并消除准入惊群
将同步与异步非文本任务的准入唤醒改为按任务和全局队首推进,批量续租等待者,避免大量请求同时争抢 advisory lock 和数据库连接。 对 Base64 请求解析、素材解码、上游媒体执行和结果物化增加分层并发限制,复用请求素材并释放重复 Gemini wire 数据;生产 API 默认入口解析并发 16,媒体物化并发 8。 新增 1000 个同步 Gemini 图像编辑请求的模拟上游压力验收,10 MiB 输入和输出下全部成功,Heap 峰值增长约 2.58 GiB,并验证共享上传哈希、单次 attempt 与本地零落盘。 验证:go test ./... -count=1;go vet ./...;gofmt -l 无输出;kubectl kustomize deploy/kubernetes/production;10 MiB Gemini Base64 千任务压力测试通过。
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
package store
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNormalizeAndValidateQueuePolicy(t *testing.T) {
|
||||
t.Run("defaults maximum wait and preserves extensions", func(t *testing.T) {
|
||||
@@ -227,3 +231,64 @@ func TestAsyncWorkerCapacityRespectsUserGroupCeiling(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdmissionDeadlineSeparatesExecutionSlotWaitFromPolicyQueueTimeout(t *testing.T) {
|
||||
now := time.Now()
|
||||
infrastructureDeadline := admissionDeadline([]AdmissionScope{{
|
||||
ConcurrentLimit: 10,
|
||||
}})
|
||||
if wait := infrastructureDeadline.Sub(now); wait < 23*time.Hour || wait > executionSlotWaitMax+time.Second {
|
||||
t.Fatalf("execution-slot deadline wait=%s, want about %s", wait, executionSlotWaitMax)
|
||||
}
|
||||
|
||||
defaultPolicyDeadline := admissionDeadline([]AdmissionScope{{
|
||||
ConcurrentLimit: 10,
|
||||
QueueLimit: 20,
|
||||
}})
|
||||
if wait := defaultPolicyDeadline.Sub(now); wait < 599*time.Second || wait > 601*time.Second {
|
||||
t.Fatalf("default policy deadline wait=%s, want about 600s", wait)
|
||||
}
|
||||
|
||||
explicitPolicyDeadline := admissionDeadline([]AdmissionScope{{
|
||||
ConcurrentLimit: 10,
|
||||
QueueLimit: 20,
|
||||
MaxWaitSeconds: 90,
|
||||
}})
|
||||
if wait := explicitPolicyDeadline.Sub(now); wait < 89*time.Second || wait > 91*time.Second {
|
||||
t.Fatalf("explicit policy deadline wait=%s, want about 90s", wait)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueuedAdmissionCountsFIFOWaitersAsVirtualCapacity(t *testing.T) {
|
||||
scope := AdmissionScope{
|
||||
ScopeType: "platform_model",
|
||||
ScopeKey: "model-1",
|
||||
ConcurrentLimit: 1,
|
||||
Amount: 1,
|
||||
QueueLimit: 2,
|
||||
}
|
||||
for waiting := 0; waiting <= 2; waiting++ {
|
||||
if err := validateQueuedAdmissionCapacity([]admissionScopeState{{
|
||||
Scope: scope,
|
||||
Waiting: waiting,
|
||||
}}); err != nil {
|
||||
t.Fatalf("waiting=%d rejected within concurrent=1 queue=2: %v", waiting, err)
|
||||
}
|
||||
}
|
||||
err := validateQueuedAdmissionCapacity([]admissionScopeState{{
|
||||
Scope: scope,
|
||||
Waiting: 3,
|
||||
}})
|
||||
var limitErr *RateLimitExceededError
|
||||
if !errors.As(err, &limitErr) || limitErr.Reason != "queue_full" {
|
||||
t.Fatalf("fourth task error=%v, want queue_full", err)
|
||||
}
|
||||
|
||||
scope.QueueLimit = 0
|
||||
if err := validateQueuedAdmissionCapacity([]admissionScopeState{{
|
||||
Scope: scope,
|
||||
Waiting: 1,
|
||||
}}); !errors.As(err, &limitErr) || limitErr.Metric != "concurrent" {
|
||||
t.Fatalf("queue-disabled second task error=%v, want concurrent rate limit", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user