feat: add application queue priority routing
This commit is contained in:
@@ -102,6 +102,9 @@
|
||||
2. 运营端可查看企业应用,并支持按企业名称、应用名称、状态搜索。
|
||||
3. 运营端可启用、停用、编辑应用。
|
||||
4. 应用必须归属企业,并关联后续签名、模板和发送任务。
|
||||
5. 短信应用必须配置发送队列等级:普通队列或优先队列。未配置时默认普通队列;优先队列用于验证码、登录确认、交易通知等高时效短信,普通队列用于营销、通知等常规短信。
|
||||
6. 发送队列等级属于真实业务配置,必须保存到后端数据库,并在客户端、运营端创建/编辑应用时展示和可修改;不得只作为前端展示字段。
|
||||
7. 运营端代企业新增短信应用时,第一步选择企业必须使用项目通用 Select/下拉控件,选项来自真实企业 API,支持加载中、空数据、错误态,不允许写死企业列表。
|
||||
|
||||
### 4.3 签名与引流信息
|
||||
|
||||
@@ -130,6 +133,9 @@
|
||||
9. 平台批量任务只记录客户端创建的发送任务;API 调用和 CMPP 对接发送不进入批量任务。
|
||||
10. 所有来源的短信,包括平台批量任务、API 调用、CMPP 对接发送,全部按手机号维度进入短信记录。
|
||||
11. 任务进度、发送详情和短信记录实时或准实时更新。
|
||||
12. 发送入队必须按短信应用的队列等级分流到优先队列或普通队列;同等条件下优先队列消息必须先于普通队列消息被 Send Worker 消费并提交 Gateway。
|
||||
13. 优先队列只能改变待发送消息的调度顺序,不得绕过企业/应用状态、签名模板审核、通道报备、余额/授信、黑名单、风控、通道组路由、通道限速和 Gateway 连接可用性校验。
|
||||
14. 同一队列内部按创建时间、任务顺序和手机号拆分顺序保持 FIFO 或可解释的稳定排序;优先队列插队时必须可在 trace 或任务日志中追踪队列等级和入队时间。
|
||||
|
||||
### 4.6 通道配置与路由
|
||||
|
||||
@@ -169,7 +175,65 @@
|
||||
8. 报备记录保留每次导出、导入、状态变更和操作人。
|
||||
9. 发送前必须校验最终选中通道上的签名报备任务为 approved;补发切换到新通道时必须重新按新通道校验报备状态,未通过则该次发送失败。
|
||||
|
||||
### 4.8 回执与上行
|
||||
### 4.8 CMPP Gateway 与外部接入
|
||||
|
||||
第一版发送链路必须区分两类 CMPP 连接,不允许用页面状态、HTTP 占位或模拟器结果替代真实协议能力:
|
||||
|
||||
- 上游通道连接:平台作为 SP 客户端,连接运营商或供应商 SMSC,将平台已路由的短信提交到目标通道。
|
||||
- 下游客户接入:企业客户作为外部 SP 客户端,连接平台暴露的 CMPP 监听端口(生产端口 `17890`),通过 CMPP 协议向平台提交短信。
|
||||
|
||||
#### 4.8.1 上游通道连接能力
|
||||
|
||||
1. Gateway 必须按运营端通道配置连接上游 SMSC,使用通道的 `gatewayHost/gatewayPort/account/passwordCipher/srcId/cmppVersion` 完成 CMPP 2.0/3.0 connect/login。
|
||||
2. Gateway 必须校验上游 connect/login 返回码,区分 connected、auth_failed、connect_timeout、network_error、protocol_error 等状态,并回写 NestJS 真实连接状态。
|
||||
3. Gateway 必须支持每个通道配置期望连接数,建立多条长连接,并按连接维度维护 currentConnections、lastConnectedAt、lastHeartbeatAt、lastError、reconnectCount。
|
||||
4. Gateway 必须实现 ActiveTest 心跳与超时检测;连续心跳失败后连接进入 heartbeat_timeout/reconnecting,重连成功前该连接不可参与发送。
|
||||
5. Gateway 必须支持断线自动重连、指数退避或固定退避、最大重试间隔、重连日志和状态回写。
|
||||
6. Gateway 必须维护 CMPP sequenceId 与平台 messageId、submitId、channelId 的映射,submit resp 和 deliver 回执必须能追溯到原短信记录和提交尝试。
|
||||
7. Gateway 必须实现真实 CMPP Submit,包括短信内容编码、长短信拆分、RegisteredDelivery、serviceId、srcId、destTerminalId、msgFmt、feeType/feeCode 等字段映射。
|
||||
8. Gateway 必须消费 NestJS 投递的 `SubmitCommand` 队列或等价内部接口;提交成功、提交失败、超时均必须回传 `SubmitResult`,不得只停留在 API 侧入队。
|
||||
9. Gateway 必须按通道连接和窗口容量控制并发,处理窗口满、SMSC 慢响应、sequence 回绕、连接断开时的在途消息状态。
|
||||
10. Gateway 不承担业务审核、计费、签名报备、通道组路由、黑名单或敏感词判断;这些由 NestJS 完成,Gateway 只执行已授权通道提交与协议事件回传。
|
||||
|
||||
#### 4.8.2 下游客户 CMPP 接入能力
|
||||
|
||||
1. Gateway 必须监听生产 CMPP 端口 `17890`,作为平台侧 CMPP Server 接收企业客户系统连接;该端口不是 HTTP 健康检查或控制接口。
|
||||
2. Gateway 必须按企业应用生成的 CMPP 接入参数校验客户 connect/login,包括企业代码、账号、密码、CMPP 版本、源 IP 白名单、应用状态、企业状态、连接数上限。
|
||||
3. 客户端应用的 IP 白名单必须对 CMPP 下游连接生效;未命中白名单、应用停用、企业停用、密码错误、超过连接数上限时必须拒绝连接并记录系统日志。
|
||||
4. Gateway 必须维护应用级下游连接状态,回写 applicationId、tenantId、connectionId、currentConnections、desiredConnections、lastHeartbeatAt、lastError,运营端企业应用列表和连接详情必须来自这些真实状态。
|
||||
5. Gateway 必须实现下游 ActiveTest、Terminate、异常断开处理;断开后连接数和状态必须及时回写。
|
||||
6. Gateway 必须处理客户提交的 CMPP Submit,将手机号、内容、源地址、企业应用、客户消息序号等转换为平台发送请求。
|
||||
7. 下游 CMPP Submit 进入平台后,不创建客户端批量任务,但必须按手机号维度创建 `sms_message_record`,source 标记为 `cmpp`,并保留客户侧 sequence/msgId 映射。
|
||||
8. 下游 CMPP Submit 必须复用 NestJS 发送前校验:企业/应用状态、IP 白名单、签名/模板报备、模板匹配策略、风控、黑名单、余额/授信、运营商识别、通道组路由。
|
||||
9. 对客户 Submit 的响应必须符合 CMPP 协议:参数错误、鉴权失败、余额不足、模板或签名未通过、无可用通道、风控拒绝等应映射为明确失败状态;已接收进入平台发送链路时返回成功并生成可追踪平台 messageId。
|
||||
10. Gateway 必须支持平台最终回执向下游客户连接投递 Deliver Receipt;若客户连接已断开,应按策略缓存、重试或记录投递失败,不能丢失平台最终状态。
|
||||
11. Gateway 必须支持下游客户上行接入场景:收到运营商上行后,按接入号、手机号、应用、时间窗口匹配并向客户连接推送 Deliver,上行同时入库。
|
||||
12. 下游客户连接与上游通道连接必须隔离管理:客户侧账号密码不能用于连接上游通道,上游通道账号密码也不能作为客户接入凭据。
|
||||
|
||||
#### 4.8.3 回执、上行与幂等
|
||||
|
||||
1. Gateway 必须解析上游 deliver receipt,将 DELIVRD、UNDELIV、EXPIRED、REJECTD 等供应商状态归一化为平台 delivered、failed、unknown、timeout 等状态。
|
||||
2. Gateway 必须解析上游普通 deliver 上行短信,携带手机号、接入号、内容、接收时间、通道和原始报文摘要回传 NestJS。
|
||||
3. Gateway 回传 `SubmitResult`、`ReceiptEvent`、`UplinkEvent` 时必须包含 traceId、messageId、submitId 或可映射字段、channelId、gatewayMessageId、sequenceId,保证短信详情能展示完整历史尝试。
|
||||
4. 重复 submit resp、重复 receipt、迟到旧通道 receipt 必须交由 NestJS 幂等处理;Gateway 不得因本地缓存丢失而生成无法追踪的重复业务事件。
|
||||
5. Gateway 需要保留最小运行日志和指标:连接数、登录失败次数、心跳失败次数、submit TPS、submit resp 延迟、receipt 延迟、队列积压、重连次数、协议错误。
|
||||
6. Gateway 控制服务 `/health` 只能表示进程存活;真实验收必须检查上下游连接状态、队列消费、submit/receipt/uplink 事件闭环。
|
||||
|
||||
#### 4.8.4 当前实现缺口标记
|
||||
|
||||
截至当前版本,Go Gateway 已有 HTTP 控制服务、健康检查、连接上游 SMSC 的 `ConnectChannel` 控制入口、gocmpp 协议 spike 和队列消息结构;但仍缺少生产验收所需的完整能力:
|
||||
|
||||
- 未实现 `17890` 入站 CMPP Server 监听。
|
||||
- 未实现下游客户 connect/login 鉴权、IP 白名单、应用级连接数限制和连接状态回写。
|
||||
- 未实现下游 CMPP Submit 到平台发送请求的转换。
|
||||
- 未实现客户侧 SubmitResp、最终 Deliver Receipt 和上行 Deliver 投递。
|
||||
- 未实现 Gateway 消费 `SubmitCommand` 并真实 submit 到上游通道的 worker。
|
||||
- 未实现上游 deliver receipt 和普通上行 deliver 的生产解析与事件回传闭环。
|
||||
- 未实现多连接窗口管理、在途消息恢复、断线重连后的消息状态处理。
|
||||
|
||||
这些缺口未补齐前,不能把 CMPP 对接发送、17890 端口联调、客户账号密码鉴权、客户 IP 白名单或真实网关 submit/receipt/uplink 作为“生产已验收通过”。
|
||||
|
||||
### 4.9 回执与上行
|
||||
|
||||
1. 通道回执接入后更新发送记录状态。
|
||||
2. 回执状态至少包括提交成功、提交失败、发送成功、发送失败、未知、超时。
|
||||
@@ -182,7 +246,7 @@
|
||||
9. 完全匹配不到的上行短信仍需入库,并展示为未匹配。
|
||||
10. 客户端可查看本企业上行短信,运营端可查看全平台上行短信。
|
||||
|
||||
### 4.9 账户计费
|
||||
### 4.10 账户计费
|
||||
|
||||
1. 客户端可查看充值套餐、购买或申请充值套餐、查看账单流水。
|
||||
2. 发送创建时按短信内容计费条数、企业应用客户单价或套餐规则生成预估费用,计费条数只按 70/67 字规则拆分;不按移动、联通、电信配置不同客户价。
|
||||
@@ -236,6 +300,7 @@
|
||||
|
||||
- 支持新增、编辑、启用、停用应用。
|
||||
- 支持配置回调地址、IP 白名单、应用密钥、日发送限额。
|
||||
- 支持配置发送队列等级:普通队列、优先队列;默认普通队列,变更后只影响新创建或新入队的发送消息。
|
||||
- 支持配置“不符合模板的短信”处理策略:拒绝发送、人工审核、直接发送。
|
||||
- 支持配置应用级风控阈值:单任务最大号码数、重复号码比例、非法号码比例、黑名单命中比例、非工作时间大批量发送策略、短时间任务创建频控。
|
||||
- 默认阈值:重复号码比例 30%、非法号码比例 10%、黑名单命中比例 5%、同一企业/应用 10 分钟内最多创建 10 次任务。
|
||||
@@ -279,6 +344,8 @@
|
||||
- 企业应用列表展示 CMPP 连接数;点击连接数打开连接详情弹窗,内容包含连接 id、状态、连接建立时间、最近心跳时间、上次提交时间、窗口占用等。
|
||||
- 企业应用连接详情支持删除连接;删除连接必须调用真实后端接口或 Gateway 回写接口,并写入系统日志。
|
||||
- 企业应用列表提供 CMPP 连接参数查看与一键复制能力,参数来源于真实应用/通道配置,不允许只在前端拼接假数据。
|
||||
- 企业应用新增/编辑必须展示发送队列等级,并真实保存普通队列或优先队列配置;列表或详情应能看到该配置,便于运营核对高优先级应用。
|
||||
- 企业应用新增时选择企业必须使用通用下拉控件和真实企业接口;下拉控件的视觉、尺寸、禁用态、错误态应与系统内其他 Select 保持一致。
|
||||
|
||||
### 5.12 运营端审核
|
||||
|
||||
@@ -432,6 +499,7 @@
|
||||
- Go CMPP Gateway 作为独立服务部署,不和 NestJS 业务后台耦合。
|
||||
- 第一版支持真实 CMPP 2.0/3.0 长连接能力,后续可扩展 SGIP、SMGP、HTTP 通道。
|
||||
- 网关负责通道连接、登录认证、长连接保活、submit、deliver、active test、重连、滑动窗口、sequence 管理、回执与上行接收。
|
||||
- 网关必须同时覆盖上游通道客户端能力和下游客户服务端能力;两类连接的账号、密码、IP 白名单、连接数、状态回写和消息映射必须隔离管理。
|
||||
- NestJS 业务后台负责企业、应用、模板、签名、报备、审核、计费、风控、路由决策和发送任务编排。
|
||||
- NestJS 与 Go Gateway 之间通过 Redis/BullMQ 队列或内部 gRPC/HTTP 通信;第一版建议使用队列提交发送指令、队列回传提交结果和回执事件。
|
||||
- Go Gateway 不直接承担业务审核、账务扣费、签名报备判断,只执行已被业务后台路由后的通道提交。
|
||||
@@ -483,24 +551,27 @@
|
||||
|
||||
1. API 创建批量任务。
|
||||
2. 拆分号码和变量,生成 message_record。
|
||||
3. 写入数据库并投递 send.queue。
|
||||
4. Send Worker 消费消息,校验黑名单、敏感词、限额。
|
||||
5. 使用可配置号码前缀正则识别运营商;识别不出时按移动处理。
|
||||
6. 使用手机号段库识别号码省份和城市;识别不出省份时按全国路由处理。
|
||||
7. 按企业应用绑定的对应运营商通道组执行路由:通道组只能是移动、联通、电信之一,发送时必须同时满足路由规则运营商、通道组运营商、通道组明细 carrier 与号码识别运营商一致;再校验通道本体 carrier 为对应运营商或三网;最后先匹配省网通道,再匹配全国通道,不得直接绑定或 fallback 到非授权单通道。
|
||||
8. 过滤业务 disabled、连接离线、认证失败、心跳超时或无可用连接数的通道。
|
||||
9. 通过通道限速器控制 TPS。
|
||||
10. 调用 Gateway Adapter 提交短信。
|
||||
11. 写入 submit 状态。
|
||||
12. Submit rejected、submit timeout、Gateway 连接断开或未提交成功、receipt failed 等场景按通道组策略补发到下一可用全国通道;unknown、超过 72 小时、超过通道组补发时间上限或关闭补发时不再补发。
|
||||
13. Receipt Worker 接收回执并更新最终状态。
|
||||
14. 补发过程必须保持幂等、计费一致和 trace 可查,最终成功只扣一次客户费率。
|
||||
15. 统计任务进度。
|
||||
3. 写入数据库并准备投递发送队列。
|
||||
4. 根据短信应用的队列等级写入 priority_send.queue 或 normal_send.queue,或在同一 BullMQ 队列中写入可验证的 priority 值;数据库中的 message_record/submit trace 必须保留队列等级。
|
||||
5. Send Worker 优先消费优先队列,再消费普通队列;多实例部署时必须避免普通队列持续抢占导致优先队列失效。
|
||||
6. Send Worker 消费消息,校验黑名单、敏感词、限额。
|
||||
7. 使用可配置号码前缀正则识别运营商;识别不出时按移动处理。
|
||||
8. 使用手机号段库识别号码省份和城市;识别不出省份时按全国路由处理。
|
||||
9. 按企业应用绑定的对应运营商通道组执行路由:通道组只能是移动、联通、电信之一,发送时必须同时满足路由规则运营商、通道组运营商、通道组明细 carrier 与号码识别运营商一致;再校验通道本体 carrier 为对应运营商或三网;最后先匹配省网通道,再匹配全国通道,不得直接绑定或 fallback 到非授权单通道。
|
||||
10. 过滤业务 disabled、连接离线、认证失败、心跳超时或无可用连接数的通道。
|
||||
11. 通过通道限速器控制 TPS;优先队列不得突破通道配置的供应商 TPS 和连接窗口上限。
|
||||
12. 调用 Gateway Adapter 提交短信。
|
||||
13. 写入 submit 状态。
|
||||
14. Submit rejected、submit timeout、Gateway 连接断开或未提交成功、receipt failed 等场景按通道组策略补发到下一可用全国通道;unknown、超过 72 小时、超过通道组补发时间上限或关闭补发时不再补发。
|
||||
15. Receipt Worker 接收回执并更新最终状态。
|
||||
16. 补发过程必须保持幂等、计费一致和 trace 可查,最终成功只扣一次客户费率。
|
||||
17. 统计任务进度。
|
||||
|
||||
### 8.3 500 条/秒实现建议
|
||||
|
||||
- 创建任务与发送解耦,提交接口只负责入库和投递队列。
|
||||
- Send Worker 多实例部署,每实例处理固定通道分片或队列分片。
|
||||
- 发送调度必须支持优先队列和普通队列:优先队列消息在同等通道和限速条件下先被消费;普通队列不能被永久饿死,应通过批次配额、老化策略或可配置调度比例保证恢复。
|
||||
- 使用 Redis Token Bucket 或本地令牌桶加 Redis 协调实现通道限速。
|
||||
- 单条发送记录以 message_id 全局唯一,所有提交和回执处理幂等。
|
||||
- 批量插入 message_record,避免逐条事务。
|
||||
@@ -520,6 +591,7 @@
|
||||
### 9.2 短信配置
|
||||
|
||||
- sms_application:短信应用。
|
||||
- sms_application.queue_priority 或等价字段:应用发送队列等级,取值 normal/priority,默认 normal。
|
||||
- sms_signature:短信签名。
|
||||
- signature_material:签名证明材料。
|
||||
- sms_template:短信模板。
|
||||
@@ -1098,18 +1170,27 @@
|
||||
4. Send Worker。
|
||||
5. 通道路由。
|
||||
6. Redis 限速。
|
||||
7. Go Gateway 提交 CMPP。
|
||||
8. Submit Resp 处理。
|
||||
9. 回执处理。
|
||||
10. 上行短信处理。
|
||||
11. 72 小时未知转超时。
|
||||
12. 任务进度统计。
|
||||
7. 上游通道 CMPP connect/login、ActiveTest、断线重连和连接状态回写。
|
||||
8. Gateway 消费 SubmitCommand 并真实 submit 到上游通道。
|
||||
9. Submit Resp 解析、sequence/messageId 映射和提交状态回传。
|
||||
10. Deliver Receipt 解析、重复/迟到回执幂等回传。
|
||||
11. 普通 Deliver 上行解析和上行入库。
|
||||
12. 下游客户 CMPP Server 监听 `17890`。
|
||||
13. 下游客户 connect/login 鉴权、IP 白名单、应用状态和连接数校验。
|
||||
14. 下游客户 CMPP Submit 转平台发送请求,source=cmpp,不创建客户端批量任务。
|
||||
15. 平台最终回执和上行向下游客户连接投递。
|
||||
16. 72 小时未知转超时。
|
||||
17. 任务进度统计。
|
||||
|
||||
验收标准:
|
||||
|
||||
- 平台创建的批量任务只记录客户端任务。
|
||||
- 平台任务、API 调用、CMPP 对接发送全部按手机号维度进入短信记录。
|
||||
- 支持 submit resp、deliver 回执、上行短信、超时补偿。
|
||||
- Gateway `/health` 只表示进程存活,不等于 CMPP 发送链路验收通过。
|
||||
- `17890` 必须是真实 CMPP Server 监听,能完成客户 connect/login 鉴权、IP 白名单校验和 submit 接入。
|
||||
- Gateway 必须真实消费 SubmitCommand 并向上游通道 submit,submit resp、receipt、uplink 事件必须进入 NestJS 后端闭环。
|
||||
- 客户 CMPP 接入发送不创建客户端批量任务,但所有号码必须进入短信记录并可追踪客户侧 sequence/msgId 与平台 messageId。
|
||||
|
||||
### 阶段 8:查询、统计、验收
|
||||
|
||||
|
||||
Reference in New Issue
Block a user