feat(queue): 增加非文本模型分布式准入队列
使用 PostgreSQL 统一同步与异步非文本任务的并发准入、持久化等待和 Worker 容量分配,并将生产 API 与独立 Worker 角色拆分。 补充策略管理、共享契约、OpenAPI、Kubernetes 双节点 Worker 清单及跨节点验收脚本;未默认启用任何生产 queue_size 策略。 已在原基线完成 Go、前端、迁移、Shell、Kustomize 与长任务容量验收;合入最新主干后将重新执行发布门禁。
This commit is contained in:
@@ -42,6 +42,10 @@ type ModelRateLimitStatus struct {
|
||||
ModelCooldownUntil string `json:"modelCooldownUntil,omitempty"`
|
||||
Concurrent RateLimitMetricStatus `json:"concurrent"`
|
||||
QueuedTasks float64 `json:"queuedTasks"`
|
||||
WaitingSyncTasks int `json:"waitingSyncTasks,omitempty"`
|
||||
WaitingAsyncTasks int `json:"waitingAsyncTasks,omitempty"`
|
||||
OldestQueueWaitSeconds float64 `json:"oldestQueueWaitSeconds,omitempty"`
|
||||
QueueLimit int `json:"queueLimit,omitempty"`
|
||||
RPM RateLimitMetricStatus `json:"rpm"`
|
||||
TPM RateLimitMetricStatus `json:"tpm"`
|
||||
LoadRatio float64 `json:"loadRatio"`
|
||||
@@ -151,6 +155,9 @@ func (s *Store) ListModelRateLimitStatuses(ctx context.Context) ([]ModelRateLimi
|
||||
COALESCE(to_char(m.cooldown_until AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), ''),
|
||||
COALESCE(con.active, 0)::float8,
|
||||
COALESCE(queued.waiting, 0)::float8,
|
||||
COALESCE(admission.waiting_sync, 0)::int,
|
||||
COALESCE(admission.waiting_async, 0)::int,
|
||||
COALESCE(admission.oldest_wait_seconds, 0)::float8,
|
||||
COALESCE(rpm.used_value, 0)::float8, COALESCE(rpm.reserved_value, 0)::float8, COALESCE(rpm.reset_at::text, ''),
|
||||
COALESCE(tpm.used_value, 0)::float8, COALESCE(tpm.reserved_value, 0)::float8, COALESCE(tpm.reset_at::text, '')
|
||||
FROM platform_models m
|
||||
@@ -192,6 +199,15 @@ LEFT JOIN (
|
||||
) queued_sources
|
||||
GROUP BY queued_sources.platform_model_id
|
||||
) queued ON queued.platform_model_id = m.id::text
|
||||
LEFT JOIN (
|
||||
SELECT platform_model_id::text AS platform_model_id,
|
||||
COUNT(*) FILTER (WHERE mode = 'sync') AS waiting_sync,
|
||||
COUNT(*) FILTER (WHERE mode = 'async') AS waiting_async,
|
||||
EXTRACT(EPOCH FROM now() - MIN(enqueued_at)) AS oldest_wait_seconds
|
||||
FROM gateway_task_admissions
|
||||
WHERE status = 'waiting'
|
||||
GROUP BY platform_model_id
|
||||
) admission ON admission.platform_model_id = m.id::text
|
||||
LEFT JOIN (
|
||||
SELECT DISTINCT ON (scope_key) scope_key, used_value, reserved_value, reset_at
|
||||
FROM gateway_rate_limit_counters
|
||||
@@ -231,6 +247,9 @@ ORDER BY p.priority ASC, m.model_name ASC`)
|
||||
var modelCooldownUntil string
|
||||
var concurrentCurrent float64
|
||||
var queuedTasks float64
|
||||
var waitingSyncTasks int
|
||||
var waitingAsyncTasks int
|
||||
var oldestQueueWaitSeconds float64
|
||||
var rpmUsed float64
|
||||
var rpmReserved float64
|
||||
var rpmResetAt string
|
||||
@@ -263,6 +282,9 @@ ORDER BY p.priority ASC, m.model_name ASC`)
|
||||
&modelCooldownUntil,
|
||||
&concurrentCurrent,
|
||||
&queuedTasks,
|
||||
&waitingSyncTasks,
|
||||
&waitingAsyncTasks,
|
||||
&oldestQueueWaitSeconds,
|
||||
&rpmUsed,
|
||||
&rpmReserved,
|
||||
&rpmResetAt,
|
||||
@@ -287,6 +309,12 @@ ORDER BY p.priority ASC, m.model_name ASC`)
|
||||
item.ModelCooldownUntil = modelCooldownUntil
|
||||
item.RateLimitPolicy = policy
|
||||
item.QueuedTasks = queuedTasks
|
||||
item.WaitingSyncTasks = waitingSyncTasks
|
||||
item.WaitingAsyncTasks = waitingAsyncTasks
|
||||
item.OldestQueueWaitSeconds = oldestQueueWaitSeconds
|
||||
if queueRule, ok := QueueRuleFromPolicy(policy); ok {
|
||||
item.QueueLimit = queueRule.Limit
|
||||
}
|
||||
item.Concurrent = metricStatus(concurrentCurrent, concurrentCurrent, 0, rateLimitForMetric(policy, "concurrent"), "")
|
||||
item.RPM = metricStatus(rpmUsed+rpmReserved, rpmUsed, rpmReserved, rateLimitForMetric(policy, "rpm"), rpmResetAt)
|
||||
item.TPM = metricStatus(tpmUsed+tpmReserved, tpmUsed, tpmReserved, tpmLimit(policy), tpmResetAt)
|
||||
|
||||
Reference in New Issue
Block a user