feat(routing): 引入多执行池智能调度

将 Worker 发现、路由画像、容量与执行传输抽象为平台无关接口,新增 Kubernetes 和静态容量适配器,并以 shadow 模式接入生产配置。

实现网络与容量评分、路由防抖、池队列、同步 Worker 租约、一次性执行令牌,以及提交状态不明时禁止重复分配的安全语义。

新增 0105 兼容迁移、管理接口、指标、OpenAPI 和回归测试。已执行全量 Go 测试、go vet、OpenAPI、迁移安全、Compose 与 Kustomize 验证。
This commit is contained in:
2026-08-05 22:25:37 +08:00
parent 03c0873649
commit 7786692d32
58 changed files with 4510 additions and 348 deletions
@@ -96,6 +96,14 @@ type Metrics struct {
candidateDisabledSkipped atomic.Uint64
candidateAllFullQueued atomic.Uint64
candidateRoutingOther atomic.Uint64
executionPoolSelected atomic.Uint64
executionPoolShadow atomic.Uint64
executionPoolUnavailable atomic.Uint64
executionPoolCapacityReject atomic.Uint64
routeProbeHealthy atomic.Uint64
routeProbeDegraded atomic.Uint64
routeProbeUnreachable atomic.Uint64
routeProbeUnknown atomic.Uint64
storageAliyunWrites atomic.Uint64
storageAliyunFailures atomic.Uint64
storageAliyunWriteNanos atomic.Uint64
@@ -324,6 +332,32 @@ func (m *Metrics) ObserveCandidateRouting(reason string) {
}
}
func (m *Metrics) ObserveExecutionPoolRouting(outcome string) {
switch outcome {
case "selected":
m.executionPoolSelected.Add(1)
case "shadow":
m.executionPoolShadow.Add(1)
case "capacity_rejected":
m.executionPoolCapacityReject.Add(1)
default:
m.executionPoolUnavailable.Add(1)
}
}
func (m *Metrics) ObserveRouteProbe(state string) {
switch state {
case "healthy":
m.routeProbeHealthy.Add(1)
case "degraded":
m.routeProbeDegraded.Add(1)
case "unreachable":
m.routeProbeUnreachable.Add(1)
default:
m.routeProbeUnknown.Add(1)
}
}
func (m *Metrics) ObserveObjectStorage(event string, provider string, bytes int64, duration time.Duration) {
provider = strings.ToLower(strings.TrimSpace(provider))
if duration < 0 {
@@ -612,6 +646,18 @@ func (m *Metrics) Handler(provider MetricsSnapshotProvider, issuer, audience str
{"all_full_queued", m.candidateAllFullQueued.Load()},
{"other", m.candidateRoutingOther.Load()},
})
outcomeCounters(w, "easyai_gateway_execution_pool_routing_total", "Execution-pool routing decisions by bounded outcome.", []outcomeValue{
{"selected", m.executionPoolSelected.Load()},
{"shadow", m.executionPoolShadow.Load()},
{"unavailable", m.executionPoolUnavailable.Load()},
{"capacity_rejected", m.executionPoolCapacityReject.Load()},
})
outcomeCounters(w, "easyai_gateway_route_probe_total", "Non-billable route probes by resulting state.", []outcomeValue{
{"healthy", m.routeProbeHealthy.Load()},
{"degraded", m.routeProbeDegraded.Load()},
{"unreachable", m.routeProbeUnreachable.Load()},
{"unknown", m.routeProbeUnknown.Load()},
})
storageProtocolCounters(w, "easyai_gateway_storage_write_attempts_total", "Object storage write attempts by bounded protocol.",
m.storageAliyunWrites.Load(), m.storageS3Writes.Load(), m.storageServerMainWrites.Load())
storageProtocolCounters(w, "easyai_gateway_storage_write_failures_total", "Object storage write failures by bounded protocol.",