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

7.2 KiB
Raw Blame History

阶段 0 技术 Spike 最小工程计划

目标

阶段 0 只验证第一版最大技术风险:NestJS 入队、Go Gateway 消费、模拟 CMPP 提交、submit resp、deliver 回执、上行事件回传、断线重连和 500 条/秒链路能力。

本阶段不实现完整业务审核、风控、计费、报备、路由后台,也不从零手写完整 CMPP 协议栈。

1. 目录结构建议

当前仓库先保留现有 React + TypeScript + Vite 原型作为根目录前端。阶段 0 建议以最小增量方式补齐后端和网关 Spike 目录:

.
├── 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.commandsNestJS -> Go Gateway,单号码发送指令。
  • cmpp.submit.resultsGo Gateway -> NestJSsubmit resp 结果。
  • cmpp.receipt.eventsGo Gateway -> NestJSdeliver 回执事件。
  • cmpp.uplink.eventsGo Gateway -> NestJS,上行短信事件。

统一信封

每条消息必须包含:

  • schemaVersion:当前固定为 v1
  • messageType:消息类型。
  • traceId:贯穿 API、队列、网关、回执的链路 ID。
  • messageId:平台单号码短信 ID,全局唯一。
  • channelId:业务后台选定的通道 ID。
  • createdAtISO 8601 时间。

发送指令

SubmitCommand 由 NestJS 或 Send Worker 产生。必须包含 tenantIdapplicationIdsubmitIdphoneNumbercontentsignaturetemplateIdbillingUnitsroutecmppretry

Go Gateway 不根据签名、模板、账户余额做业务判断,只读取 route.cmppAccountCodecmpp.serviceIdcmpp.srcIdcmpp.registeredDeliverycmpp.msgFmt 等协议提交所需字段。

结果和事件

  • SubmitResult 必须回传 sequenceIdgatewayMessageIdsubmitStatussubmittedAt
  • ReceiptEvent 必须回传 gatewayMessageIdsequenceIdreceiptStatusdeliveredAtrawStatus
  • UplinkEvent 必须回传 phoneNumberdestIdcontentreceivedAtsequenceId

详细结构以 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. 所有消息具备 traceIdmessageIdchannelIdsequenceId 或可追踪映射。
  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 条/秒压测脚本和报告。