Files
lislgosms/docs/phase-0-technical-spike-plan.md

161 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 阶段 0 技术 Spike 最小工程计划
## 目标
阶段 0 只验证第一版最大技术风险:NestJS 入队、Go Gateway 消费、模拟 CMPP 提交、submit resp、deliver 回执、上行事件回传、断线重连和 500 条/秒链路能力。
本阶段不实现完整业务审核、风控、计费、报备、路由后台,也不从零手写完整 CMPP 协议栈。
## 1. 目录结构建议
当前仓库先保留现有 React + TypeScript + Vite 原型作为根目录前端。阶段 0 建议以最小增量方式补齐后端和网关 Spike 目录:
```text
.
├── docs/
│ ├── contracts/
│ │ ├── gateway-queue-messages.schema.json
│ │ └── examples/
│ ├── phase-0-technical-spike-plan.md
│ └── phase-0-spike-progress.md
├── api/
│ ├── README.md
│ └── src/
│ └── spike/
│ └── queue-contracts/
├── gateway/
│ ├── README.md
│ ├── cmd/
│ │ ├── gateway/
│ │ └── smsc-simulator/
│ └── internal/
│ ├── cmpp/
│ ├── queue/
│ ├── connection/
│ ├── tracker/
│ └── metrics/
└── tools/
└── spike/
└── validate-gateway-queue-contract.mjs
```
阶段 1 再决定是否迁移为正式 monorepo:
- `web/`:当前 React 原型。
- `api/`NestJS + Prisma + BullMQ。
- `gateway/`Go CMPP Gateway。
- `infra/`PostgreSQL、Redis、MinIO、Prometheus、Grafana 的 compose 与部署配置。
## 2. NestJS 与 Go Gateway 队列消息格式
阶段 0 采用 Redis + BullMQ 作为通信基线。NestJS 只负责投递已经完成业务校验和路由决策后的发送指令;Go Gateway 只负责协议提交和事件回传。
### 队列命名
- `cmpp.submit.commands`NestJS -> Go Gateway,单号码发送指令。
- `cmpp.submit.results`Go Gateway -> NestJSsubmit resp 结果。
- `cmpp.receipt.events`Go Gateway -> NestJSdeliver 回执事件。
- `cmpp.uplink.events`Go Gateway -> NestJS,上行短信事件。
### 统一信封
每条消息必须包含:
- `schemaVersion`:当前固定为 `v1`
- `messageType`:消息类型。
- `traceId`:贯穿 API、队列、网关、回执的链路 ID。
- `messageId`:平台单号码短信 ID,全局唯一。
- `channelId`:业务后台选定的通道 ID。
- `createdAt`ISO 8601 时间。
### 发送指令
`SubmitCommand` 由 NestJS 或 Send Worker 产生。必须包含 `tenantId``applicationId``submitId``phoneNumber``content``signature``templateId``billingUnits``route``cmpp``retry`
Go Gateway 不根据签名、模板、账户余额做业务判断,只读取 `route.cmppAccountCode``cmpp.serviceId``cmpp.srcId``cmpp.registeredDelivery``cmpp.msgFmt` 等协议提交所需字段。
### 结果和事件
- `SubmitResult` 必须回传 `sequenceId``gatewayMessageId``submitStatus``submittedAt`
- `ReceiptEvent` 必须回传 `gatewayMessageId``sequenceId``receiptStatus``deliveredAt``rawStatus`
- `UplinkEvent` 必须回传 `phoneNumber``destId``content``receivedAt``sequenceId`
详细结构以 `docs/contracts/gateway-queue-messages.schema.json` 为准。
## 3. Go Gateway 最小能力清单
阶段 0 最小 Go Gateway 只做以下能力:
1. 读取一个通道配置:网关地址、端口、企业代码、账号、密码、接入号、CMPP 版本、窗口大小、心跳间隔、重连间隔。
2. 基于 gocmpp 或评估后的协议库完成 connect、active test、submit、deliver、terminate。
3. 消费 `cmpp.submit.commands`,提交到模拟 SMSC。
4. 将 submit resp 写入 `cmpp.submit.results`
5. 将 deliver 回执写入 `cmpp.receipt.events`
6. 将上行短信写入 `cmpp.uplink.events`
7. 维护 `messageId -> sequenceId -> gatewayMessageId` 的追踪映射。
8. 支持断线重连,重连后继续消费后续消息。
9. 暴露最小健康检查和指标:连接状态、队列积压、提交 TPS、submit 成功率、回执延迟、重连次数。
10. 支持模拟 SMSC:正常响应、慢响应、断线、重复回执、窗口满。
## 4. gocmpp 与 cmpp-gateway 技术评估任务
评估对象:
- `bigwhite/gocmpp`:优先评估为协议层依赖。
- `JoeCao/cmpp-gateway`:只作为连接管理、重连、SEQID/MSGID 追踪和模拟器设计参考。
任务清单:
1. License:确认依赖许可是否允许第一版商业项目使用。
2. 维护活跃度:确认最近提交、Issue、PR、Go module 支持情况。
3. 协议覆盖:确认 CMPP 2.0/3.0、connect、submit、deliver、active test、terminate 支持情况。
4. 编解码可靠性:验证长短信、UCS2、GBK、状态报告、上行短信解析。
5. 连接模型:评估长连接、心跳、窗口、并发 submit、断线重连。
6. 追踪能力:验证 sequenceId、msgId、平台 messageId 的映射方案。
7. 模拟器:复用或参考模拟 SMSC 的响应、慢响应、断线和重复回执能力。
8. 改造边界:判断直接依赖、轻量 fork、或只参考实现的取舍。
9. 风险清单:列出协议层缺口、生产部署风险、测试补充项。
## 5. 500 条/秒 Spike 压测指标
压测只验证链路调度能力,不验证完整业务规则。
### 场景
1. NestJS 批量投递 30 秒,共 15000 条发送指令。
2. Go Gateway 消费队列并提交到模拟 SMSC。
3. 模拟 SMSC 立即返回 submit resp,并在 1 到 3 秒内返回 deliver。
4. 重复执行单连接和多连接两个场景。
5. 插入异常场景:模拟 SMSC 慢响应、短暂断线、重复回执。
### 指标
- 入队吞吐:P50、P95、P99,每秒入队数必须稳定达到 500。
- 消费吞吐:每秒消费并提交数,30 秒平均不低于 500。
- 端到端延迟:入队到 submit resp P95 小于 2 秒。
- 回执延迟:deliver 到 NestJS 消费 P95 小于 10 秒。
- 错误率:submit command 处理失败率小于 0.1%。
- 重试率:异常场景下可观测且不造成重复最终状态。
- 队列积压:压测停止后 30 秒内归零。
- 资源指标:CPU、内存、Redis ops、连接重连次数。
- 幂等指标:重复回执只产生一条最终状态更新,多余回执进入历史记录。
## 6. 阶段 0 验收标准
1. 跑通一条模拟短信链路:NestJS 入队 -> Go Gateway 提交 -> submit resp -> deliver 回执 -> NestJS 更新状态。
2. Go Gateway 断线后可重连,并能继续消费后续消息。
3. 所有消息具备 `traceId``messageId``channelId``sequenceId` 或可追踪映射。
4. 队列消息 Schema、示例消息和校验脚本通过。
5. 完成 gocmpp 与 JoeCao/cmpp-gateway 评估记录,明确最终依赖方式。
6. 完成 500 条/秒压测报告,包含瓶颈、资源使用和下一阶段优化建议。
7. 文档记录 Go Gateway 哪些能力复用协议库,哪些服务层能力由本项目自研。
## 阶段 0 执行顺序
1. 创建阶段 0 计划文档、队列消息 Schema、示例消息和校验脚本。
2. 创建 Go Gateway Spike 骨架和模拟 SMSC 骨架。
3. 创建 NestJS Spike 骨架,完成 BullMQ 入队和事件消费。
4. 接入 Redis 本地环境,跑通模拟链路。
5. 评估 gocmpp 与 JoeCao/cmpp-gateway。
6. 完成 500 条/秒压测脚本和报告。