coord.md 新增 ARB-019/020/021 三章仲裁章节,修正 ARB-001。 - coord.md: 新增 ARB-019/020/021(student/parent/admin-portal 24 项) - coord.md: 修正 ARB-001(admin P2 预留/schema 文件名/classes 数据源) - 004 §4: 依赖图加 PBFF→DataAna+Msg - 004 §7.2: push-gateway→Redis 软失败标注 - 004 §11.4: 错误码前缀矩阵(11 服务+i18n key) - 004 §11.5: ActionState 信封规范(降级模式方案 B) - matrix §1: 依赖矩阵加 PBFF 边 - matrix §2: 移除 api-gateway 为 iam gRPC 消费方 - matrix §4: admin-portal→teacher-bff - matrix §5: 移除 /sse+鉴权头统一 - matrix §6: 错误码表补 i18n key 列 - 15 个 issue.md: 仲裁结论回写 - push-gateway_contract: 移除 /sse+鉴权头改 X-Internal-Token - packages/contracts: 新建包 ADMIN_* 权限点常量 AI: coord
184 lines
15 KiB
Markdown
184 lines
15 KiB
Markdown
# push-gateway 问题记录
|
||
|
||
> 负责人:ai02
|
||
> 关联:[coord.md](../coord.md)、[contracts/push-gateway_contract.md](../contracts/push-gateway_contract.md)、[push-gateway 02 架构设计](../../../services/push-gateway/docs/02-architecture-design.md)
|
||
> 规则:AI 遇到问题时在此追加条目,coord 仲裁后更新状态
|
||
|
||
---
|
||
|
||
## §0 已有仲裁核查(ai02 复审 02 文档对总裁裁决的回写情况)
|
||
|
||
> 本节为 ai02 在批次 0 等待期对 president-final-rulings 已裁决事项的回写核查。
|
||
> 裁决来源:[president-final-rulings.md](../../president-final-rulings.md) §1.5 / §3.3 / §4.2 / §4.3 / §4.4 / §7.2 / §3.4
|
||
> 核查日期:2026-07-10
|
||
> 核查结论:5 项裁决中 **0 项已完全回写**、**1 项部分回写**、**4 项未回写**
|
||
|
||
### 核查矩阵
|
||
|
||
| 裁决编号 | 主题 | 裁决要求(摘要) | 02 文档现状 | 核查结论 | 状态 |
|
||
| ------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------- | ------------ |
|
||
| ISSUE-053 | Kafka topic 命名 | 02 §5.1 topic 改为 `edu.notification.requested`,禁止抽象名 `edu.*.events` | §5.1 仍写 `edu.notification.events` / `NotificationRequested` | ❌ 未回写 | 待 ai02 修复 |
|
||
| ISSUE-055 | /readyz 软失败 | push-gateway /readyz 对 Kafka 软失败(失败仅告警 + `degraded: true` + 返 200,不返 503) | §6.7 仅 Redis PING 硬失败返 503,无 Kafka 软失败逻辑 | ❌ 未回写 | 待 ai02 修复 |
|
||
| ISSUE-056 | 设计决策记录章节 | 02 §5.4 改名为"设计决策记录:gRPC vs HTTP 协议选型(coord 已采纳 P1)",正文标注"coord 已采纳" | 02 无"设计决策记录"章节 | ❌ 未回写 | 待 ai02 修复 |
|
||
| ISSUE-058 | Redis SET 启动重建 | 02 §3.1 补充"Hub 启动时遍历内存连接 SADD + EXPIRE 60s + 清空旧 instanceID 成员";/readyz Redis 失败仅告警不阻塞;metrics 暴露 `push_gateway_redis_set_rebuild_total`;文档化 60s 不一致窗口 | §3.1/§8.4 仅描述运行期 SADD/SREM,无启动重建;§6.7 Redis 硬失败返 503(与"仅告警不阻塞"冲突);无重建指标;无 60s 窗口说明 | ❌ 未回写 | 待 ai02 修复 |
|
||
| ARB /internal/push 契约(§4.2) | 第一版 /internal/push 契约 | coord "as-is" 采纳 ai02 02 §4.2 作为第一版契约,仅在 ai10 异议时调整 | 02 §4.2 已定义 `{user_id, event, data, ttl?}` → `{success, delivered, online}` | ✅ 已落地 | 无需动作 |
|
||
|
||
### 核查结论
|
||
|
||
- **ISSUE-053/055/056/058 共 4 项须 ai02 在批次 4 启动前回写到 02 文档**(president-final-rulings §3.4 明确"批次 4 启动前"完成回写)
|
||
- **ARB /internal/push 契约已落地**,无需动作;但 ai10 若提出异议(如 batch 接口/异步回调),coord 会公布差异点
|
||
- ISSUE-058 中"/readyz Redis 失败仅告警不阻塞"与 ISSUE-055"软失败规则"形成耦合:Redis 作为 push-gateway 必需依赖本应硬失败,但 ISSUE-058 裁决要求"仅告警不阻塞"以避免雪崩 —— **此耦合需 coord 明确优先级**(见下方 ISSUE-006-ai02)
|
||
|
||
---
|
||
|
||
## §1 问题列表(提请 coord 仲裁)
|
||
|
||
### ISSUE-001-ai02:SSE 端点是否提供(跨文档三方冲突)
|
||
|
||
- **提请方**:ai02
|
||
- **日期**:2026-07-10
|
||
- **类型**:契约不明确
|
||
- **描述**:SSE 端点(`/sse`)在三个文档中存在冲突:
|
||
- [push-gateway_contract.md](../contracts/push-gateway_contract.md) §1.2 列出 `GET /sse` 端点,认证 JWT
|
||
- [matrix.md](../matrix.md) §5 HTTP 接口矩阵列出 `push-gateway (ai02) | SSE | /sse`
|
||
- [02-architecture-design.md](../../../services/push-gateway/docs/02-architecture-design.md) §10 明确建议"不支持 SSE,WebSocket 已够用,避免协议膨胀"
|
||
- 01-understanding.md 完全未提及 SSE
|
||
- 实际代码无 `/sse` 实现,`gin-contrib/sse` 仅为 gin 间接依赖
|
||
- **建议方案**:采纳 02 文档建议 —— **push-gateway 不提供 SSE,仅 WebSocket**。理由:
|
||
1. 单一协议降低维护成本与测试矩阵
|
||
2. SSE 单向下行 + 文本协议,不适合未来 reconnect/ack 双向协议
|
||
3. 各 portal 已规划 WebSocket 接入([coord-cross-review.md](../../coord-cross-review.md))
|
||
- **影响方**:ai13/ai14/ai15(前端需统一走 WebSocket,移除 SSE 兜底)、ai10(msg 不需调 /sse)、coord(更新 matrix.md §5 与 contract.md)
|
||
- **状态**:待 coord 仲裁
|
||
|
||
### ISSUE-002-ai02:内部 API 鉴权命名三方不一致
|
||
|
||
- **提请方**:ai02
|
||
- **日期**:2026-07-10
|
||
- **类型**:契约不明确
|
||
- **描述**:内部 API 鉴权头与环境变量在四处不一致:
|
||
- **代码**([handler.go#L30](../../../services/push-gateway/internal/ws/handler.go#L30) + [config.go#L41](../../../services/push-gateway/internal/config/config.go#L41)):`X-Internal-Key` 头 + `INTERNAL_API_KEY` 环境变量
|
||
- **02 文档** §4.2/§6.1:`X-Internal-Token` 头 + `INTERNAL_API_TOKEN` 环境变量
|
||
- **ai-allocation.md** §5:`X-Internal-Key`
|
||
- **president-final-rulings.md** §7.2:"X-Internal-Token 重命名"(暗示应改为 Token)
|
||
- **contract.md** §1.2:`内网 mTLS`(第四种方案!)
|
||
- **建议方案**:统一为 `X-Internal-Token` + `INTERNAL_API_TOKEN`(对齐总裁裁决 §7.2)。理由:
|
||
1. 总裁裁决已明确倾向 Token 命名
|
||
2. "Token"语义比"Key"更准确(共享密钥而非公私钥对)
|
||
3. mTLS 在 P5 阶段引入成本过高,且 K8s 内网已有 NetworkPolicy 隔离,共享密钥足够
|
||
- **影响方**:ai10(msg 调用方需用相同头名)、coord(更新 contract.md 与 matrix.md §5 移除 mTLS)
|
||
- **状态**:待 coord 仲裁
|
||
|
||
### ISSUE-003-ai02:单节点容量目标 50k vs 10w+ 冲突
|
||
|
||
- **提请方**:ai02
|
||
- **日期**:2026-07-10
|
||
- **类型**:契约不明确
|
||
- **描述**:单节点最大连接数目标在两份文档冲突:
|
||
- [modules/push-gateway/README.md](../../../docs/modules/push-gateway/README.md) §7:"单节点最大连接数 50k,超出时拒绝新连接"
|
||
- [02-architecture-design.md](../../../services/push-gateway/docs/02-architecture-design.md) §11:"单实例最大连接数 10w+"
|
||
- [01-understanding.md](../../../services/push-gateway/docs/01-understanding.md) §5 引用 pending-features:"单节点支撑 10w+ 连接"
|
||
- **建议方案**:统一为 **10w+**(对齐 02 文档与 pending-features)。理由:
|
||
1. 10w+ 是 P5 设计目标(pending-features 权威)
|
||
2. Go goroutine-per-connection + 64KB send chan 单连接约 20-30KB,10w 连接约 2-3GB,单节点可承载
|
||
3. 50k 目标过于保守,与横向扩展方案不匹配
|
||
- **影响方**:coord(更新 modules/README.md §7)、ai02(02 §11 已正确)
|
||
- **状态**:待 coord 仲裁
|
||
|
||
### ISSUE-004-ai02:contract.md 内部端点路径 /internal/send vs /internal/push 冲突
|
||
|
||
- **提请方**:ai02
|
||
- **日期**:2026-07-10
|
||
- **类型**:契约不明确
|
||
- **描述**:内部单推端点路径在 contract.md 与代码/02 文档冲突:
|
||
- [contract.md](../contracts/push-gateway_contract.md) §1.2 + §2.4:`POST /internal/send`
|
||
- **代码**([main.go#L58](../../../services/push-gateway/main.go#L58))+ **02 文档** §4.2:`POST /internal/push`
|
||
- 总裁裁决 §4.2 已"as-is 采纳 ai02 02 §4.2",即应使用 `/internal/push`
|
||
- **建议方案**:contract.md 统一改为 `POST /internal/push`(对齐总裁裁决与代码)。此为 ai02 自主回写范畴,不需 coord 仲裁动作,仅在此登记以便 coord 复核。
|
||
- **状态**:ai02 自行修复(见 contracts 回写)
|
||
|
||
### ISSUE-005-ai02:审计表(6 字段)设计缺失
|
||
|
||
- **提请方**:ai02
|
||
- **日期**:2026-07-10
|
||
- **类型**:契约不明确
|
||
- **描述**:[ai-allocation.md](../../ai-allocation.md) §5 将"审计表(6 字段)"列为 ai02 设计重点,但:
|
||
- 01-understanding.md §2 明确"不持有业务状态""无 DB"
|
||
- 02-architecture-design.md §3 明确"无数据库。所有状态在内存 + Redis"
|
||
- 两份文档均无审计表设计
|
||
- **疑问**:审计表是否要求 push-gateway 引入 MySQL/PostgreSQL?这与"无 DB"定位冲突。可能的解读:
|
||
1. push-gateway 引入轻量审计表(如 SQLite/Redis Stream 持久化推送记录)
|
||
2. 审计表由 msg 服务维护(msg 已落库),push-gateway 仅通过 Kafka 事件回流
|
||
3. ai-allocation 表述过度,审计需求由 msg 满足
|
||
- **建议方案**:方案 2(审计由 msg 维护,push-gateway 仅同步返结果)。理由:保持 push-gateway 无 DB 定位,避免引入持久化层增加运维复杂度。
|
||
- **影响方**:ai10(msg 需确认审计字段是否覆盖 push-gateway 推送结果)、coord(澄清 ai-allocation §5 表述)
|
||
- **状态**:待 coord 仲裁
|
||
|
||
### ISSUE-006-ai02:ISSUE-058 与 ISSUE-055 对 Redis /readyz 失败策略耦合冲突
|
||
|
||
- **提请方**:ai02
|
||
- **日期**:2026-07-10
|
||
- **类型**:契约不明确
|
||
- **描述**:两份裁决对 push-gateway /readyz Redis 检查失败的策略存在表述冲突:
|
||
- **ISSUE-055**([president §3.3](../../president-final-rulings.md)):将 Redis 列为"必需依赖",失败返 503 触发 Pod 重启
|
||
- **ISSUE-058**([president §4.3](../../president-final-rulings.md)):"/readyz Redis 检查失败时仅告警不阻塞,与 ISSUE-055 协调,避免雪崩"
|
||
- **冲突点**:Redis 是 push-gateway 跨实例广播的必需依赖(必需 → 503),但实例重启不能恢复 Redis 故障,且重启会丢失本地连接表加剧雪崩(应仅告警)
|
||
- **建议方案**:明确为 **Redis 软失败**(仅告警 + `degraded: true` + 返 200),从 ISSUE-055 必需依赖列表中移除 push-gateway → Redis。理由:
|
||
1. push-gateway 重启不解决 Redis 故障
|
||
2. Redis 故障时单实例仍能服务本地连接(仅跨实例广播失效)
|
||
3. 雪崩风险高于短暂不一致
|
||
- **影响方**:coord(澄清两裁决优先级)
|
||
- **状态**:待 coord 仲裁
|
||
|
||
### ISSUE-007-ai02:02 文档缺 ADR / 非功能性需求 / 失败模式章节(不符业界架构文档规范)
|
||
|
||
- **提请方**:ai02
|
||
- **日期**:2026-07-10
|
||
- **类型**:工作量超批
|
||
- **描述**:02-architecture-design.md 不符合业界架构文档规范(arc42 / C4 模型):
|
||
1. **无 ADR 章节**:[modules/push-gateway/README.md](../../../docs/modules/push-gateway/README.md) §8 提到"待 P5 交付时补充 ADR 记录",但 02 文档未落地。关键决策(gorilla/websocket 选型、Redis Pub/Sub vs Stream、心跳间隔 30s/60s 选型、10w 容量依据)无 ADR
|
||
2. **无非功能性需求章节**:无可用性 SLO(如 99.9%)、安全合规、容量 SLA
|
||
3. **无失败模式/混沌工程章节**:实例崩溃、Redis 故障、网络分区、Kafka 消费积压场景下的降级策略缺失
|
||
4. **§11 容量表无依据**:10w 连接的内存/CPU/网络带宽估算缺失
|
||
- **建议方案**:在批次 4(P5)补全 02 文档 §14-§17 四个章节(ADR / 非功能性需求 / 失败模式 / 容量估算)。预估工作量:1-1.5 天。
|
||
- **影响方**:ai02(自主补全)
|
||
- **状态**:待 coord 确认是否纳入 P5 Must Have
|
||
|
||
---
|
||
|
||
## §2 已自主修复的文档偏差(ai02 直接修复,不需 coord 仲裁)
|
||
|
||
> 以下为 01-understanding.md 与现码不符的偏差,ai02 在批次 0 自主修复
|
||
|
||
| # | 位置 | 偏差 | 修复方向 |
|
||
| --- | ---------- | ------------------------------------------------------------------------------ | -------------------------------------------------- |
|
||
| 1 | 01 §3.2 | `/readyz` 标"无(待实现)",实际已实现(仅未检查 Redis) | 改为"已实现,仅返连接数,待补 Redis PING" |
|
||
| 2 | 01 §3.2 | `/metrics` 标"无(待实现)",实际已挂载 promhttp | 改为"已实现,待补自定义指标" |
|
||
| 3 | 01 §3.2 | `/internal/push` `/internal/broadcast` 标"待补鉴权",实际已实现 X-Internal-Key | 改为"已实现 X-Internal-Key 校验(DevMode 跳过)" |
|
||
| 4 | 01 §6 + §7 | Dockerfile 标"❌ 单阶段",实际为多阶段(缺非 root/healthcheck/ldflags) | 改为"⚠️ 多阶段但缺非 root + healthcheck + ldflags" |
|
||
| 5 | 01 §7.1 #6 | 引用 `main.go L44-46` 行号过期,鉴权状态错误 | 更新行号并改为"已实现" |
|
||
| 6 | 01 全文 | 未提及 SSE 端点(contract.md/matrix.md 列出但 02 建议不支持) | 待 ISSUE-001 仲裁后补充结论 |
|
||
| 7 | 01 全文 | 未提及审计表(ai-allocation §5 设计重点) | 待 ISSUE-005 仲裁后补充 |
|
||
|
||
---
|
||
|
||
## §3 历史问题
|
||
|
||
(暂无)
|
||
|
||
---
|
||
|
||
## §4 仲裁结论(coord,2026-07-10)
|
||
|
||
> 详见 [coord.md](../coord.md) §17 ARB-015
|
||
|
||
| ISSUE | 仲裁结论 | 状态 |
|
||
| -------------------- | --------------------------------------------------------------- | --------------------- |
|
||
| 001(SSE 端点) | ✅ 不支持 SSE,仅 WebSocket;coord 移除 contract/matrix 的 /sse | 已裁决(§17 ARB-015) |
|
||
| 002(鉴权命名) | ✅ 统一 `X-Internal-Token` + `INTERNAL_API_TOKEN`(总裁 §7.2) | 已裁决(§17 ARB-015) |
|
||
| 003(容量目标) | ✅ 统一 10w+(对齐 02 文档 + pending-features) | 已裁决(§17 ARB-015) |
|
||
| 004(端点路径) | ✅ 统一 /internal/push(ai02 已自行修复) | 已裁决(§17 ARB-015) |
|
||
| 005(审计表) | ✅ 方案 2:审计由 msg 维护,push-gateway 无 DB | 已裁决(§17 ARB-015) |
|
||
| 006(Redis /readyz) | ✅ Redis 软失败(仅告警不阻塞,ISSUE-058 覆盖 ISSUE-055) | 已裁决(§17 ARB-015) |
|
||
| 007(02 缺 ADR/NFR) | ✅ P5 批次 4 补全 02 §14-§17 四章节 | 已裁决(§17 ARB-015) |
|