perf(worker): 解耦准入调度与远端执行

原因:线上 P24 同构验收确认两台香港 Worker 的全局容量为 48,但跨地域逐行准入事务每轮只能形成 8 个活跃租约,队列最老等待超过 15 分钟。\n\n影响:新增可配置的异步准入 dispatcher 角色;生产两地 API 负责准入和过期回收,Worker 仅执行 River job。当前主库同站点 API 可低延迟填满容量,主库切换后另一地 API 通过既有数据库锁安全接管;未配置环境变量时保持原 Worker 一体化行为。\n\n验证:Go 全量测试、go vet、gofmt、真实 PostgreSQL 1000 任务双进程回归、前端 lint/test/build、Kubernetes server-side dry-run、Compose、ShellCheck、cluster/manual release tests 全部通过。
This commit is contained in:
2026-08-01 23:24:30 +08:00
parent 9c093974a1
commit a4046c2b81
10 changed files with 96 additions and 27 deletions
@@ -136,33 +136,37 @@ func TestAsyncWorkerThousandConcurrentSchedulingAcceptance(t *testing.T) {
serverCtx, cancelServer := context.WithCancel(ctx)
defer cancelServer()
server := httptest.NewServer(NewServerWithStores(serverCtx, config.Config{
AppEnv: "test",
HTTPAddr: ":0",
DatabaseURL: databaseURL,
IdentityMode: "hybrid",
JWTSecret: "test-secret",
BillingEngineMode: "observe",
CORSAllowedOrigin: "*",
ProcessRole: "api",
AsyncQueueWorkerEnabled: true,
AsyncWorkerHardLimit: 1000,
AsyncWorkerInstanceHardLimit: 1000,
AsyncWorkerRefreshIntervalSeconds: 1,
AppEnv: "test",
HTTPAddr: ":0",
DatabaseURL: databaseURL,
IdentityMode: "hybrid",
JWTSecret: "test-secret",
BillingEngineMode: "observe",
CORSAllowedOrigin: "*",
ProcessRole: "api",
AsyncQueueWorkerEnabled: true,
AsyncAdmissionDispatcherEnabled: true,
AsyncAdmissionDispatcherConfigured: true,
AsyncWorkerHardLimit: 1000,
AsyncWorkerInstanceHardLimit: 1000,
AsyncWorkerRefreshIntervalSeconds: 1,
}, apiDB, apiCoordinationDB, apiDB, slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError}))))
defer server.Close()
workerServer := httptest.NewServer(NewServerWithStores(serverCtx, config.Config{
AppEnv: "test",
HTTPAddr: ":0",
DatabaseURL: databaseURL,
IdentityMode: "hybrid",
JWTSecret: "test-secret",
BillingEngineMode: "observe",
CORSAllowedOrigin: "*",
ProcessRole: "worker",
AsyncQueueWorkerEnabled: true,
AsyncWorkerHardLimit: 1000,
AsyncWorkerInstanceHardLimit: 1000,
AsyncWorkerRefreshIntervalSeconds: 1,
AppEnv: "test",
HTTPAddr: ":0",
DatabaseURL: databaseURL,
IdentityMode: "hybrid",
JWTSecret: "test-secret",
BillingEngineMode: "observe",
CORSAllowedOrigin: "*",
ProcessRole: "worker",
AsyncQueueWorkerEnabled: true,
AsyncAdmissionDispatcherEnabled: false,
AsyncAdmissionDispatcherConfigured: true,
AsyncWorkerHardLimit: 1000,
AsyncWorkerInstanceHardLimit: 1000,
AsyncWorkerRefreshIntervalSeconds: 1,
}, workerDB, workerCoordinationDB, workerDB, slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError}))))
defer workerServer.Close()
+3
View File
@@ -138,6 +138,9 @@ func NewServerWithStores(
logger.Info("asynchronous queue worker disabled for this process")
}
}
if cfg.RunsAsyncAdmissionDispatcher() {
server.runner.StartAsyncAdmissionDispatcher(ctx)
}
if cfg.RunsBackgroundWorkers() {
server.runner.StartBillingSettlementWorker(ctx)
server.runner.StartTaskHistoryWorkers(ctx)