Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

MQTT 与用量事件协议

MQTT 承载三类消息:

方向TopicQoS功能
ScootGate → broker{prefix}/usage1非权威用量事件
broker → ScootGate{prefix}/auth/notify1授权快照更新提示
broker → ScootGate{prefix}/routing/notify1路由快照更新提示

默认 prefix 为 scootgate。ScootGate 使用 clean session,每次连接后重新订阅 两个 notify topic;keep-alive 为 30 秒,连接错误后退避 1 秒重连。

Broker URL

支持:

  • mqtt://host[:port]tcp://host[:port](默认 1883);
  • mqtts://host[:port]ssl://tls://tcps://(默认 8883)。

URL 不允许 path。生产使用 TLS scheme 和专用服务身份。

快照通知

两个 notify topic 使用同一 payload:

{"version": 42}

约束:

  • JSON body 最大 4 KiB;
  • version 为 u64;
  • 只有严格大于本地当前版本才触发拉取;
  • malformed、重复、旧版本和乱序通知被忽略;
  • 通知只触发受认证 HTTPS 全量拉取,不直接修改状态;
  • 500ms debounce 会合并突发通知;
  • 通知丢失不影响正确性,定时轮询仍会发现版本。

控制面应使用 QoS 1 发布,不需要 retain;即使发生重复投递也必须保持幂等。

用量事件投递

请求完成后,事件先写入本地磁盘 outbox,再向 {prefix}/usage 发布:

  • MQTT QoS 1;
  • retain = false
  • 收到匹配 PUBACK 后删除 outbox 文件;
  • broker 断线或进程重启后重放;
  • event_id 在重放时保持不变;
  • 消费方必须按 event_id 去重。

outbox 满或不可写时,ScootGate 按 drop_newest 丢弃新事件并增加健康计数, 但 Provider API 数据面继续服务。

Unix 平台上,outbox 目录权限为 0700,事件文件权限为 0600;写入采用临时文件、 fsync 和原子 rename。运维备份或诊断不得把这些文件上传到第三方系统。

Usage event schema 2

示例:

{
  "schema": 2,
  "event_id": "gate-a-1784700000000000000-17",
  "instance_id": "gate-a",
  "tenant_id": "tenant-1",
  "key_id": "key-1",
  "provider": "openai_compatible",
  "path": "/v1/chat/completions",
  "status": 200,
  "outcome": "relayed",
  "public_model": "chat-fast",
  "upstream_model": "gpt-4o-mini",
  "backend_id": "openai-primary",
  "selection_attempts": 1,
  "attempted_backend_ids": ["openai-primary"],
  "failure_stage": null,
  "send_state": "response_received",
  "charge_state": "provider_reported",
  "routing_version": 41,
  "prompt_tokens": 12,
  "completion_tokens": 7,
  "request_body_bytes": 138,
  "response_body_bytes": 512,
  "first_byte_ms": 220,
  "duration_ms": 640,
  "ts_unix_ms": 1784700000000
}

字段

字段类型说明
schemau32固定 2
event_idstring稳定幂等键
instance_idstringScootGate 节点
tenant_id / key_idstring授权快照中的身份
providerstringopenai_compatibleanthropic_messages
pathstring客户端 Provider API 路径
statusu16返回客户端的状态码
outcomestring请求结果分类
public_modelstring/null客户端公共模型
upstream_modelstring/null改写后的 Provider 模型
backend_idstring/null最后选择/尝试的 backend
selection_attemptsu32总选择次数
attempted_backend_idsarray按顺序记录尝试
failure_stagestring/null失败阶段
send_statestringProvider 发送状态
charge_statestringtoken/计费不确定性
routing_versionu64snapshot 版本;static 模式为表 fingerprint
prompt_tokens / completion_tokensu64/nullProvider 原生 usage
request_body_bytes / response_body_bytesu64relay 字节计数
first_byte_msu64/nullProvider 首包延迟
duration_msu64请求总时长
ts_unix_msu64事件创建 Unix 毫秒时间

send_state

含义
not_sent选择前拒绝,未尝试 backend
definitely_not_sent尝试失败且能证明 Provider 请求字节未发出
possibly_sent请求可能到达 Provider,不能安全重试
response_received已收到 Provider 响应头

charge_state

含义
not_sentProvider 未收到请求
unknown可能发送/已响应,但 Provider 未报告 token usage
provider_reported至少一个 token 字段来自 Provider 原生 usage

缺失 token 必须是 JSON null,不能根据字节数估算。

常见 failure_stage

  • selection
  • reselect_exhausted
  • egress_connect
  • provider_tls
  • provider_write
  • response_head
  • provider_auth
  • null(正常 relay 或 Provider 429 等已收到响应场景)

常见 outcome

  • relayed
  • throttled
  • bad_request
  • unknown_model
  • unsupported_model_capability
  • no_backend_available
  • bad_gateway
  • gateway_timeout
  • upstream_auth_rejected

数据最小化

事件和 outbox 明确不包含:

  • 客户端原始 API key;
  • Provider credential;
  • Authorization / x-api-key header;
  • prompt、messages、tools 或响应正文;
  • Provider 完整 URL query;
  • TLS key/certificate 内容。

该协议固定为非权威观测通道。需要权威计费时必须使用单独设计,不能仅依赖 MQTT QoS 1、磁盘 outbox 或此 schema。