feat(ha): 网关多副本安全 —— 事件订阅改队列组,杜绝重复落库/重复计费

去单点的代码层基础:dispatcher/mcp-go 本就靠队列组可多副本,但网关侧的 eval/usage/
status/config 订阅是广播(nc.Subscribe),多网关副本下每条会被每个副本各处理一遍 →
评测/状态重复写 PG、token 用量重复累加(日预算翻倍)、config 请求多份重复应答。

改为 QueueSubscribe + contract.QueueGateway 队列组:组内每条事件/请求只一个副本处理。
(dispatcher/mcp-go 的 config 变更广播订阅保持 nc.Subscribe 不动——每副本都要热更新。)

验证:
- 单测 TestGatewayQueueDedup:2 网关副本订阅,发 50 条 eval,合计处理 50 次(非 100)。
- live:2 dispatcher 副本提 8 任务,队列组自动 4/4 分摊。

至此进程级全部可水平复制。剩 NATS 集群 / 网关 LB / PG·Redis·Milvus 基础设施 HA 属部署期。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-06-26 13:10:49 +08:00
parent 2e3cb8105d
commit 19df6f3a94
4 changed files with 62 additions and 9 deletions
+4
View File
@@ -25,6 +25,10 @@ const (
QueueToolsGo = "mcp-go-workers" // mcp-go 队列组(多副本负载均衡)
QueueToolsPy = "mcp-py-workers" // mcp-py 队列组
// QueueGateway 是网关侧事件订阅/配置应答的队列组:多网关副本下,每条
// eval/usage/status 事件与每个 config 请求只由组内一个副本处理,避免重复落库/重复应答(HA)。
QueueGateway = "gateway-workers"
// 服务探活:dispatcher 既无 HTTP 端点也不挂工具,单独用一个 core NATS
// request-reply 心跳主题让控制面(管理端「服务状态」)能判定它在不在线。
SubjectHealthDispatcher = "sundynix.health.dispatcher"