326 lines
41 KiB
Markdown
326 lines
41 KiB
Markdown
# 发送监控页面重做:需求、统计口径与页面方案
|
||
|
||
- 版本:V1.0实施版,2026-09-06。
|
||
- 状态:2026-09-06用户授权实施中;原型中的名称、条数和比率全部为设计示例。
|
||
- 本轮范围:用户已授权按方案修改、提交、推送、部署测试环境;默认阈值留空。原设计阶段及当前验证边界分别见第11、12节和testing-progress。
|
||
- 原型入口:[原型说明](prototypes/sending-monitor-20260906/README.md)。
|
||
|
||
## 1. 目标与页面定位
|
||
|
||
将运营端 `/admin/monitor` 从通道清单和总体数量页改为发送质量监控工作台:运营人员能快速回答“哪个通道/哪个应用签名发送异常、哪个时效指标下降、样本够不够、何时发生、采用什么阈值”。
|
||
|
||
提供三种监控,并将异常集中展示到右上角现有“预警中心”:
|
||
|
||
| 监控类型 | 聚合维度 | 执行频率 | 每次选取的提交窗口 | 指标 |
|
||
|---|---|---|---|---|
|
||
| 行业通道监控 | 通道 × 运营商 | 每5分钟 | 最近5分钟 | 5秒、20秒、1分钟到达率 |
|
||
| 验证码监控 | 企业应用 × 签名(含企业隔离键) | 每5分钟 | 最近5分钟,最终发送正文包含“验证码” | 5秒、20秒、1分钟到达率 |
|
||
| 整体兜底监控 | 企业应用 × 签名(含企业隔离键) | 每10分钟 | 最近30分钟 | 1分钟、5分钟、20分钟到达率 |
|
||
|
||
这是按固定周期评估的准实时业务监控,不宣称秒级持续告警。“刷新页面”刷新已计算的最新快照,不重启全量统计;界面同时展示样本窗口、评估时刻、最近计算时间和数据是否延迟。
|
||
|
||
系统监控 `/admin/system-monitoring` 继续负责CPU、内存、磁盘及服务指标;数据统计/签名质量报表继续承担长周期报表。不得把三类页面的分母和统计口径互相替换。
|
||
|
||
## 2. 原需求解释与待确认点
|
||
|
||
以下是为使方案可实施而采用的建议,不视为用户已确认:
|
||
|
||
1. “5到达率”按“5分钟到达率”处理。
|
||
2. “兜底”暂指**全部短信的整体质量兜底**,包含验证码和行业短信,与前两类监控允许重叠;不是仅筛选补发或兜底通道。若实际意图是后者,必须先定义哪些通道/重试事件属于兜底,并在发送事实中冻结标记,不能仅凭最终channelId推断。
|
||
3. “提交”建议指首次实际发往上游的 Submit,不包括尚在平台排队、定时未到、审核未通过或路由前拦截的消息。用户提交至平台的排队时长另作辅助信息,不混进供应商回执时延;若要验证码端到端SLA,应另加“平台受理起算”指标。
|
||
4. “到达”采用**平台收到有效成功回执**的可观测口径。页面可保留用户熟悉的“5秒到达率”等列名,但须常驻说明“以平台收到成功回执为准”。不等于终端实测到达或用户已读。
|
||
5. 各指标下限、最低样本量初始值待根据真实基线确定。原型中的100条、90%/95%/98%等只是示例,不作为生产默认值或行业标准自动启用。
|
||
6. 未满观察时长的短信不计为失败;采用第4节的按指标成熟样本口径。同一行三个指标可有不同分母,必须明确展示。
|
||
|
||
## 3. 当前实现核对与差距
|
||
|
||
本轮只读基线:2026-09-06,`main / 69e3d73`,本地相对跟踪`origin/main`领先2项;`ls-remote`回读远端为`442dda711d5c9f778f3f76fd6d8fd69f14414ce6`。工作区有其他任务的文档修改及草稿,均未作为本轮成果或纳入原型数据。未连接PostgreSQL、Redis或服务器,因此下列是代码事实,性能数字仅为设计目标。
|
||
|
||
| 位置 | 当前代码事实 | 本次设计影响 |
|
||
|---|---|---|
|
||
| [AdminMonitorPage.tsx](../src/apps/admin/AdminMonitorPage.tsx) | 调用通道列表和listMonitor,展示运行通道、总体成功率、消息总量;手动刷新 | 没有三类时效窗口、监控范围与告警策略 |
|
||
| [uplink.queries.ts](../api/src/operations/queries/uplink.queries.ts) 的monitor | 按messageWhere分组当前状态,另读最近消息/回执/上行;本页调用未提供有界时间窗口 | 不应让新自动刷新继续触发全表总体聚合 |
|
||
| [AdminLayout.tsx](../src/layouts/AdminLayout.tsx) | 全局用轻量接口轮询;预警中心含安全和系统告警;另有待审与报备任务提醒 | 新发送质量告警加入预警中心,不放入报备任务提醒,不复用重型dashboard接口 |
|
||
| [schema.prisma](../api/prisma/schema.prisma) | 有SmsMessageRecord、SmsSubmitRecord、分片审计、SmsReceiptRecord与UpstreamReceiptInbox | 能关联业务消息、发送尝试、分片和回执;还没有本方案的规则、快照与告警实体 |
|
||
| [upstream/submit.go](../gateway/internal/upstream/submit.go) | submitResult中的SubmittedAt为结果构造时刻,submitPart内才发生SendReqPkt | 现有submittedAt不能未经验证就当作最初发包时间计算5秒指标 |
|
||
| [upstream/deliver.go](../gateway/internal/upstream/deliver.go) | 回执事件DeliveredAt赋值time.Now().UTC() | 这是Gateway收到回执的时间,不是供应商DoneTime;不能将字段名直接理解为终端时间 |
|
||
| [send-receipt.service.ts](../api/src/send-chain/send-receipt.service.ts) | 入站回执持久化到Inbox,再匹配处理;重复回执有receiptKey | 复用现有持久化与匹配结果,区分Gateway接收时间和API处理时间,避免处理积压扭曲5秒指标 |
|
||
|
||
旧需求[5.10运营看板与监控](first-version-development-requirements.md)及[TC-ADMIN-011](system-functional-test-cases.md)由三类质量监控及“运行概况”承接。按2026-09-06用户追加要求,运行概况删除最近发送/回执/上行三组列表,并删除其后端查询与响应字段;保留状态统计、通道列表及基础设施跳转。独立短信记录、状态报告和上行记录页面/API保持原有职责。统计逻辑不复用运营看板的分片到达率。
|
||
|
||
## 4. 统一统计口径
|
||
|
||
### 4.1 计数单位与去重
|
||
|
||
- 行业通道:按`messageRecordId + submitId + channelId`唯一的**一次业务短信发送尝试**计1次,随后按真实收件号码运营商分组。一个三网通道拆为移动、联通、电信三行,不能按通道配置的“三网”重复累计同一条;未知运营商单列并提示数据质量。
|
||
- 验证码与整体兜底:按`tenantId + applicationId + messageRecordId`去重,每条业务短信计1条。补发、换通道不增加分母,也不重置第一次实际提交时间;成功可来自任一有效完整发送尝试,但不能将不同尝试的零散成功分片拼成一次完整成功。
|
||
- 行业通道中,原通道尝试失败、换通道成功分别反映各自质量;后者不得反向把前者改成成功。该业务短信在应用×签名监控中仍只计一次。
|
||
- 同号码多次不同业务发送各计一次,不按号码去重;网关重放同一事件不增加计数。批量多号码按平台稳定业务消息ID逐条统计。
|
||
- 长短信以完整业务消息为单位:该次有效尝试的全部必要分片成功回执收齐才成功,成功时刻取最后必要分片的首次成功回执接收时刻。分片总数必须来自真实发送快照,不能用当前计费单位随意替代。
|
||
- 实际已提交但上游拒绝、响应超时或最终失败的尝试保留在分母;未发包的路由/连接失败不伪造Submit样本,进入运行概况的“提交前失败”。对于“可能已写出但无法确认”的网络边界,单列不确定样本和完整性状态,不静默排除并显示健康。
|
||
- 未要求回执、不支持成功回执、无法匹配、缺少关键时间的记录,不制造100%或0%指标。展示不可评估数量和原因,触发数据质量提示;已确认提交且正常应有回执但未收到的样本,在成熟后计为未按时成功。
|
||
|
||
签名采用发送时已解析的`signatureId`及名称快照;应用用稳定ID,tenantId始终在后端隔离键中。签名重命名不拆历史序列;删除后历史快照仍可查。没有可验证签名/应用映射的历史数据单列“未识别”,不按当前同名签名猜测归并。验证码判断是最终展开、重组后的**发送正文包含字面量“验证码”**,只识别一次保存布尔值和规则版本;不以模板分类、登录图形验证码或模糊关键词替代,不存储验证码具体值到监控表。
|
||
|
||
### 4.2 时间定义
|
||
|
||
- `t0`:行业通道为该次尝试第一次成功写出Submit的时间;验证码/整体兜底为该业务消息所有有效尝试中最早的实际Submit时间。
|
||
- `ts`:满足完整成功条件的Gateway成功回执接收时刻;重复成功取首次、重复事件幂等。记录`timestampSource`和精度,禁止用API事务处理时间/updatedAt替代。
|
||
- 时间统一存UTC,页面显示北京时间,精确到毫秒计算;阈值边界使用`ts - t0 <= h`,5.000秒算5秒内,5.001秒不算。负延迟或时钟明显异常单列不可评估并暂停受影响告警,不强制归零。
|
||
- 真正Submit时间采集是实施前置项:扩展现有Gateway结果/分片事件携带`firstWireSubmitAt`及时间源,随已有耐久事件持久化,保持旧消费者兼容。不得靠解析全量文本日志实现常态监控;必须验证进程崩溃、无SubmitResp、分片和回执先到的边界,不能只在accepted结果里补时间。
|
||
- 旧数据缺少精确起点时可显示“历史口径不可比”,但不参与新5秒告警;不把SubmitResp时刻回填成已核实发包时刻。
|
||
|
||
### 4.3 周期、成熟样本与公式
|
||
|
||
设评估边界为`T`,5分钟任务在北京时间整5分钟对齐,10分钟任务在整10分钟对齐;按`[T-W, T)`选取提交样本,左闭右开。`W`为5分钟或30分钟。
|
||
|
||
对每个时效`h`独立计算。`B`是观察截止时刻,实时初评时`B=T`;行业/验证码补齐时`B=T+60秒`,详见本节末尾:
|
||
|
||
```text
|
||
Q = 窗口内本维度可纳入时效统计的唯一提交样本
|
||
M_h = { m ∈ Q | t0(m) + h <= B } # 已等满h的成熟样本
|
||
N_h = |M_h| # 可评估条数
|
||
S_h = |{ m ∈ M_h | 完整成功且0 <= ts(m)-t0(m) <= h }|
|
||
R_h = S_h / N_h × 100% # N_h=0时为null
|
||
观察中_h = |Q| - N_h
|
||
触发_h = 指标开启 且 数据完整 且 N_h>=minSamples 且 R_h<下限_h
|
||
```
|
||
|
||
重要规则:尚未等满时长的样本,即使已成功或已失败,也统一先留在“观察中”,不能只把提前成功的样本塞入分子/分母造成幸存偏差。失败、超时、未知及成熟后未回执均在分母中;`N_h<minSamples`显示“样本不足”,不触发该指标。最低条数应用于**每项指标的成熟分母**,不是整行总提交量。
|
||
|
||
示例:12:30评估兜底窗口`[12:00,12:30)`。20分钟指标仅评估12:10及以前提交的样本,12:10之后的仍观察中;1分钟与5分钟分别评估至12:29、12:25。若全窗口300条,20分钟可评估90条、其中85条按时成功,则显示94.44%(85/90),最低100条时不告警,而不是85/300=28.33%。
|
||
|
||
同一批固定成熟样本的累计成功率随时限应不下降;本页面同一行三个时限使用不同成熟子集,比率**不保证单调**,不能前端排序或修正数字。每格显示`S_h/N_h`,悬停显示观察中数量及口径。全局合计必须先加分子分母再相除,不能对各行百分比做算术平均。
|
||
|
||
**5分钟固定窗口必须补齐尾部观察样本。**行业/验证码窗口不重叠,如果只在T计算一次,最后1分钟的短信可能永远不参与1分钟指标。故T时先给出实时初评,T+60秒再对同一`[T-5分钟,T)`生成完整结果,成熟判定时刻改为T+60秒,窗口提交边界保持不变,并再等待摄取宽限。历史趋势默认展示补齐后的完整结果;当前实时行显著标注“初评,待补齐”,补齐后显示“已定稿”。这最多增加约1分钟的完整窗口确认延迟,不改变每5分钟一个统计窗口。
|
||
|
||
初评可提前产生异常提示,补齐时更新同一事件,不能将初评和补齐计为两次连续异常。连续异常/恢复次数以每个窗口的定稿结果计数;配置连续1次时允许初评先报,随后定稿证实;配置大于1次时等定稿后计数。初评异常而定稿正常,事件按“窗口补齐后解除”关闭并保留两份证据,不伪称真实业务恢复。自动业务恢复只使用定稿窗口,禁止旧窗口补齐覆盖更新窗口的状态。整体兜底的窗口每10分钟重叠,每条样本会在后续窗口中成熟并纳入;需用边界用例证明任意提交时刻都能参与各时效指标,不能据此跳过行业/验证码的补齐任务。
|
||
|
||
### 4.4 快照完整性、迟到与回算
|
||
|
||
- 每个边界T生成版本化快照,记录窗口、观察截止B、初评/定稿阶段、计算时间、规则版本、样本量、完整性、水位和指标。建议在B之后给摄取/匹配预留30秒宽限(需实测调优),统计仍按B观察,不把宽限期新增提交算入窗口;补齐也不改变窗口右边界T。
|
||
- 已在时限内被Gateway接收但晚处理的回执,按原接收时间回算;真正超时后才收到的成功回执,不得因为最终成功而提高较短时限比率。
|
||
- 水位完整不是“最近一条事件很新”:需检查相关已提交事实、未处理/未匹配回执、检查点连续性及积压。数据未齐时显示“数据延迟”,冻结该维度新的低到达率告警和自动恢复,独立提示监控管道异常;不能把监控自身故障归咎于通道。
|
||
- 同一`类型+维度+T`只有一个快照身份,回算增加revision而不重复新建。保留告警首次评估值和更正值,迟到导致误报时标记“数据修正关闭”,不伪称业务自然恢复。
|
||
- 最近30分钟兜底窗口每10分钟重叠,样本可参与多个不同T的评估;同一T内只计一次。不得把重叠窗口累计为发送总量。
|
||
- 初次纳管/配置启用后默认只对生效时间之后的提交执行告警,等待成熟样本;历史数据仅作对比。回算保留时长建议72小时,以事件完整性及成本校准,超出范围显式提示未回算,不全表补算。
|
||
|
||
## 5. 监控配置
|
||
|
||
### 5.1 行业通道
|
||
|
||
- 监控范围由运营人员在“监控通道”弹窗中搜索、勾选、移除;展示通道名称/编号、支持运营商、业务启停状态、监控是否开启、生效时间。
|
||
- 通道监控开关独立于业务通道启停,不改变通道价格、路由、连接或发送配置。关闭业务通道不自动删除监控历史;展示停用状态,已有窗口继续评估,后续无样本不虚报异常。
|
||
- 设置一套行业通道通用阈值:最低成熟条数、5秒/20秒/1分钟到达率下限,各指标可单独开启/关闭;本期不强制增加每通道独立策略,避免无需求的配置膨胀。
|
||
- 新建通道、复制通道必须在**服务端保存成功且返回新ID之后**弹窗:“是否加入行业通道监控?”说明:“如果是行业短信通道建议加入”。按钮“暂不加入”“加入监控”,显示将使用的通用阈值摘要。
|
||
- 加入动作只调用独立监控配置API;成功提示“通道已保存,已加入监控”。加入失败提示“通道已保存,加入监控失败,可重试”,不可回滚已创建通道、重复提交创建或假报全部成功;重试对同一个通道ID幂等。
|
||
- 复制不继承原通道的监控成员身份或个性设置,一律对新通道再提醒;关闭弹窗等同暂不加入,后续可在监控范围加入。原通道不受影响。无监控管理权限者看到已保存结果和权限说明,不展示可执行加入按钮。
|
||
|
||
### 5.2 验证码
|
||
|
||
- 全平台有权限范围内的企业应用×签名自动覆盖,无需逐个添加。只纳入最终正文包含“验证码”的业务短信。
|
||
- 独立通用阈值:最低成熟条数、5秒/20秒/1分钟下限,不能与行业通道配置共用同一个值对象。
|
||
- 搜索条件:企业、应用、签名、状态;详情可按运营商/通道分解定位原因,但不改变主告警键,也不把通道尝试数当主分母。
|
||
|
||
### 5.3 整体兜底与个性阈值
|
||
|
||
- 通用规则:最低成熟条数、1分钟/5分钟/20分钟下限。
|
||
- 个性规则支持“某企业应用”“某签名”“某企业应用×签名”三个作用范围。所有ID均在同一企业权限范围内校验,不能按名字匹配跨企业签名。
|
||
- 建议优先级:**应用×签名 > 签名 > 应用 > 通用**。同时匹配签名和应用时采用签名规则,界面明确显示被覆盖来源;列表显示“实际生效规则”,详情能查看完整匹配链。
|
||
- 采用最高优先级的一整套规则,避免不同来源按字段拼接难以解释。创建个性规则时预填继承值,保存为独立完整规则集;“恢复继承”删除该层覆盖并展示将生效的下级策略。
|
||
- 同层同范围唯一,重复保存更新原规则;版本号乐观锁,冲突返回409并让用户重新加载。改规则记录操作者、修改前后值、生效时间;不对历史窗口用新阈值追溯制造告警。
|
||
- 编辑页实时展示一个示例维度的最终生效策略,并提示高优先级覆盖范围。不要让用户保存后仍猜测哪套生效。
|
||
|
||
### 5.4 参数校验与生效
|
||
|
||
- 最低成熟条数为正整数;到达率下限0~100%,保留两位小数;开启的累计下限建议满足短时限≤长时限,不合理顺序提示修正。至少开启一项时效指标。
|
||
- 百分比仅展示时四舍五入,告警比较使用整数基点/精确分子分母;等于下限不告警,低于下限告警。0%下限等于该项不会因低比率触发,界面明确提示。
|
||
- 每类可配置连续异常次数(默认建议1)、连续恢复次数(默认建议2),范围1~5;站内提醒默认新异常一次,持续异常更新原事件,不周期刷屏。
|
||
- 配置成功以真实持久化为准,页面显示版本和生效时间。配置修改后从下一个周期使用新版本;旧活动事件以“规则变更”关闭并重置连续计数,不算业务恢复。
|
||
|
||
## 6. 告警生命周期与预警中心
|
||
|
||
1. 任意开启的指标在成熟样本达标且数据完整时低于下限,累计对应连续异常次数;达到阈值创建一条该维度的发送质量告警,附全部命中指标。
|
||
2. 同一类型+维度只保留一个活动告警事件,多个时效指标合并展示;使用事务唯一约束/锁防止双Worker重复。业务维度键不包含窗口T,避免每个重叠窗口新建。
|
||
3. 活动事件更新最新值、最差值、持续时长和周期记录。用户“标记已读/已知悉”只影响个人未读状态,不等于恢复或关闭统计。
|
||
4. 所有开启指标均有充分成熟样本、数据完整且不再命中下限,连续满足恢复次数后自动恢复。样本不足、无发送、数据延迟均不累计恢复;活动告警显示“暂停评估”原因。
|
||
5. 恢复后再次异常创建新事件并重新未读;配置关闭、范围移除、规则变更分别记录关闭原因,不能冒充恢复。短暂静默仅隐藏个人/授权范围通知,统计仍进行并记录到期时间。
|
||
6. 预警中心新增“发送质量告警”,展示未读活动事件数及异常维度数,点击进入`/admin/monitor?tab=alerts`;弹层样式、键盘/点击外部关闭和窄屏行为复用现有AppShell。
|
||
7. 全局角标只调用独立轻量`notification-summary`,按既有30秒节奏、聚焦及已读事件刷新。返回失败保留上次值并标记不可用,不能清零或清空其他预警域。明细列表和计数使用相同权限、过滤和去重口径。
|
||
8. 发送质量告警属于预警中心;签名清退继续在现有报备任务提醒中,待审核任务不增加这些计数。首期只做站内告警,不发短信、邮件或第三方通知,不触发自动停通道、换路由、补发。
|
||
|
||
## 7. 页面与交互
|
||
|
||
### 7.1 监控主页面
|
||
|
||
- 路由保持`/admin/monitor`。一级页签:行业通道、验证码、整体兜底、告警记录;标题操作区为刷新、阈值设置、行业页特有的监控通道。
|
||
- 顶部持续显示口径、当前窗口、计算周期、最新成功计算时间/数据延迟;30秒页面取数不等同于5/10分钟重新评估。长时间挂后台暂停轮询,恢复焦点再拉取,手动刷新节流。
|
||
- 摘要卡:监控维度数、异常维度数、样本不足维度数、窗口提交量(行业用“提交尝试”,其他用“业务短信”)。无数据时显示—/0并区别未配置、无发送、计算中与接口失败。
|
||
- 表格以异常优先:维度、窗口提交量、三个到达率、实际阈值/规则来源、状态、趋势/详情。各指标格包含百分比、成功/成熟数;低于阈值的格红色强调,观察中/样本不足中性显示,不只依赖颜色。
|
||
- 用户能筛选全部/异常/正常/样本不足/数据延迟;应用/签名支持带企业名的远程搜索、分页。筛选保存在URL,首次进入、刷新和告警深链接能还原。
|
||
- 保留“运行概况”入口显示状态统计及通道信息,通过基础设施入口查看连接和积压;删除最近消息/回执/上行列表及对应明细查询,不把业务启用标记等同实际连接健康。
|
||
|
||
### 7.2 趋势与告警详情
|
||
|
||
- 详情页/抽屉显示异常对象、类型、状态、开始/最近评估时间、规则快照及每项命中指标。
|
||
- 展示最近2小时/24小时曲线,点的时间含义为评估T;悬停显示窗口、分子分母、观察中条数和revision。阈值变更用分段线和注释,不能用今天阈值覆盖昨天曲线。
|
||
- “查看样本”跳转已有短信记录,带精确应用/签名/通道/时间/结果过滤;需有详情权限,手机号脱敏,不在告警摘要暴露正文或验证码。
|
||
- 异常、无数据、待计算、采集延迟、失败重试、权限不足、删除对象历史查看均有明确状态。配置弹窗保存失败保留输入,未保存离开有确认。
|
||
|
||
### 7.3 响应式与原型覆盖
|
||
|
||
- 原型采用项目白底侧栏、浅灰内容区、蓝色选中、紧凑表格和8px圆角;复用Breadcrumb/Button/Select/Table/Tag/Modal。
|
||
- 1600×1000完整展开;1366×768保持正文14px,表格自身横向滚动、弹窗仅Body滚动;390×844用折叠导航、横滑页签、每维度一张指标卡和全屏配置抽屉,不缩小字体挤宽表。
|
||
- 配套图覆盖三个主视图、阈值/个性规则、通道纳管提示、预警中心/详情、窄屏;均为静态示意,不含真实API、数据库或用户操作。
|
||
|
||
## 8. 数据流与性能方案
|
||
|
||
### 8.1 推荐架构
|
||
|
||
```text
|
||
已有Submit结果 / 分片审计 / 回执Inbox(耐久业务事实)
|
||
→ 独立监控Worker:增量投影、完整性校验、幂等归并
|
||
→ 短期MonitorFact + 分钟汇总桶
|
||
→ 5/10分钟调度:生成窗口快照、评估规则、维护告警事件
|
||
→ 轻量分页API / 角标摘要 → 页面
|
||
```
|
||
|
||
原则是发送热路径不等待统计查询、规则匹配或通知,也不每条短信执行多次聚合SQL。精确时间需要扩展既有耐久事件,但尽量不新增独立同步消息或额外发送事务。监控读取失败只造成监控降级,不能阻断发送;基础事实持久化本身仍遵循原发送可靠性契约,不为性能跳过必要写入。
|
||
|
||
推荐一期由独立Worker读取**既有已落库事实**做短批增量投影,避免再造一套逐短信业务Outbox;如果无法在既有事实中证明完整性,必须在技术验证阶段调整采集契约,不宣称纯查询就能准确算5秒。不能直接消费现有短信Stream的同一个consumer group分走消息,也不能依赖已ACK/XDEL的Stream作为历史账本。
|
||
|
||
### 8.2 增量、桶与精度
|
||
|
||
- 数据提取针对提交事实与回执处理结果两条游标分别维护检查点。`createdAt/id`或`updatedAt/id`排序只提供扫描位置,不能假设数据库事务提交顺序与时间戳一致;采用重叠回读+按ID幂等覆盖,并定期有界对账。扫描到未完成关联的Inbox保留待匹配集合,直到已匹配或明确异常,不越过后遗忘。
|
||
- 监控事实保持稳定source key、源版本、t0、首次完整成功时间、类型标记和维度快照;同一源重复摄取以替换贡献/脏桶重建处理,不能直接重复INCR。事实、桶版本和检查点在监控侧短事务内一致提交,崩溃可回放。
|
||
- 以提交分钟建立稀疏桶,记录计数及5秒/20秒/1分钟/5分钟/20分钟累计按时成功数。长时限成熟边界可整分钟读取;5秒/20秒成熟边界落在分钟内部,必须从索引事实补算边界秒区间,不能把整分钟全算成熟,更不能把时间四舍五入到分钟。
|
||
- 每次评估读5或30个分钟桶及最多一分钟的边界事实,不对每个通道/签名单独发SQL循环。批量处理活跃维度,监控列表只读已保存快照。
|
||
- 三类监控共享一次业务消息/正文解析投影,验证码布尔只识别一次;行业通道尝试汇总与应用业务消息汇总分别维护。禁止常态运行`content LIKE '%验证码%'`扫描业务大表,禁止反复JSON反序列化正文。
|
||
- 固定维度ID;仅有流量或配置的组合建桶,不生成“企业×应用×签名×通道×运营商”笛卡尔积。应用签名不是Prometheus高基数标签;Prometheus仅观测Worker延迟、批量大小、错误率等低基数运行指标。
|
||
- 迟到事件只将相应提交分钟标脏并合并修正其相关快照;兜底每条样本最多影响3个滚动提交窗口,再处理有必要的历史revision,禁止重算所有维度全部历史。
|
||
|
||
### 8.3 表与索引候选(设计项,不直接执行迁移)
|
||
|
||
| 候选实体 | 内容及约束 |
|
||
|---|---|
|
||
| SendingMonitorTarget | 行业通道成员、enabled、effectiveFrom、version;channelId唯一 |
|
||
| SendingMonitorRule | 类型、作用域与ID、完整阈值JSON/结构字段、版本、生效时间、操作者;同类型同作用域唯一 |
|
||
| SendingMonitorFact | sourceKind/sourceId唯一、tenant/app/signature/channel/carrier快照、t0、successAt、时间源、验证码标记、完整性与源版本;不复制手机号和正文 |
|
||
| SendingMonitorMinute | type/dimensionKey/minute/口径版本唯一,累计计数、revision;稀疏存储 |
|
||
| SendingMonitorSnapshot | type/dimensionKey/T/口径版本唯一,三个S/N、观察中、规则快照、completeAt/revision;保留历史追溯 |
|
||
| SendingMonitorAlert / AlertRead | 活动事件唯一约束、规则版本、首次/最新/最差值、状态/原因;已读按eventId+userId唯一 |
|
||
| SendingMonitorCheckpoint | 按来源/分片的扫描位置、租约、扫描上下界、对账进度、未处理缺口 |
|
||
|
||
索引按实际谓词和EXPLAIN选:事实`(dimensionKey,t0)`支持边界范围;快照`(type,T,status)`及维度历史时间索引;源表新增`(updatedAt,id)`/相关状态时间索引前先验证现有查询计划。不能仅因表很大就堆宽索引,源表新增索引会增加发送/回执写放大;DDL锁与索引创建窗口需部署评审。
|
||
|
||
参考:[PostgreSQL复合索引说明](https://www.postgresql.org/docs/current/indexes-multicolumn.html)强调前导列约束对扫描范围的作用;[Prometheus标签规范](https://prometheus.io/docs/practices/naming/)提示避免无界高基数。应用版本能力以目标数据库为准,不将文档最新版优化当作当前服务器已具备。
|
||
|
||
### 8.4 调度与资源预算
|
||
|
||
- 一期建议1个独立监控Worker,连接池上限2、并行任务1,按哈希/时间分批;每批500~2000条是压测候选值,受statement_timeout和短事务约束,自适应退避,禁止Promise.all按全部签名并发。
|
||
- 以数据库租约/唯一任务键确保每个边界T只被一个执行者持有;过期可接管,重跑幂等。不要只使用进程内setInterval防重。调度边界固定,批次可错峰,不漂移窗口定义。
|
||
- 轻量摘要API缓存15~30秒,按权限作用域及版本隔离;缓存丢失只回源汇总表,禁止回源重扫业务表。使用Redis只缓存结果,不做每条短信一个TTL键/定时器。
|
||
- 建议热事实先按2小时估算,分钟桶7天、窗口快照30天、告警及规则审计90天,再按实际合规与磁盘容量评审。72小时是候选纠错范围,不要求保留等长的全量热明细;热事实过期后的纠错从既有事实按ID有界恢复,恢复成本超预算则明确标记未回算。清理仅针对独立监控数据,按分区/小批执行,不清业务消息、回执或短信队列。
|
||
- 新增实际发包时间字段、源表索引、监控投影和回算均有成本;不能承诺“零影响”。性能验证不通过时先缩小纳管范围、降低摄取批量或部署独立读副本(需确认复制延迟),不能以提高发送并发或削弱耐久性掩盖。
|
||
|
||
### 8.5 可解释的容量估算与验收预算
|
||
|
||
令业务短信速率为λ、平均尝试数a、平均分片数s,则已有提交/分片/回执事实处理量约按`λ×a×s`增长;重复回执另计,不能仅看业务TPS。
|
||
|
||
以假设500条业务短信/秒、a=1.1、s=1为例:每5分钟15万业务短信、约16.5万次尝试;每30分钟90万业务短信。每次对这些数据重新Join三遍会产生持续负载。监控分钟汇总将周期读取转为与活跃维度和窗口长度相关,而事实摄取仍与事件量线性相关。
|
||
|
||
该假设下业务+尝试投影若约1050行/秒,72小时约2.72亿行;即使每行连索引按粗估200字节,也约54GB且未计WAL/膨胀。**因此72小时明细不能不经容量测算直接上线**;可优先缩短热事实至2小时(约756万行、粗估1.5GB),更长回算在既有事实中按ID有界恢复,或评估分区/独立存储。这是容量风险示例,不代表现环境有500TPS、该磁盘余量或该行大小。
|
||
|
||
实现验收建议预算(待基线实测校准):
|
||
|
||
- 同负载对照开启/关闭监控,发送受理/提交及回执落库P95相对恶化不超过5%,无业务错误增加,发送Stream/Inbox无持续新增积压。
|
||
- 监控新增连接不超分配池,数据库总体CPU增幅目标不超过5个百分点,磁盘I/O和WAL写放大单独记录;不以单次低峰截图证明高峰达标。
|
||
- 周期任务P95在30秒内完成、必须小于调度周期;快照/摘要API P95≤300ms(不含公网延迟);不足则标记性能验收未通过,禁止藏掉延迟指标。
|
||
- 数据超过一个采集SLA(初值30秒)未完整时标为延迟;两个评估周期无新完整快照时告警“监控计算异常”。按真实依赖延迟校准,不误关正常短信发送。
|
||
- 先用脱敏历史快照/隔离数据集验证1倍及峰值2倍规模,覆盖高签名基数、长短信、重试与回执突发。真实发送压力测试另需授权;本设计阶段未运行压测。
|
||
|
||
## 9. API与权限边界(拟定)
|
||
|
||
统一使用`/api/admin/sending-monitor`,不重用系统监控或旧monitor的全量聚合接口:
|
||
|
||
| 接口 | 用途 |
|
||
|---|---|
|
||
| GET /overview?type=... | 最新快照摘要、T、nextEvaluationAt、数据完整性 |
|
||
| GET /rows?type=...&page=... | 权限范围内分页维度、S/N/观察中、状态与生效规则 |
|
||
| GET /history?dimensionId=...&range=... | 有界历史快照及规则变更 |
|
||
| GET /targets;PUT /targets/:channelId | 行业纳管列表与幂等加入/移除,携带version |
|
||
| GET /rules;PUT /rules/:id;POST /rules | 通用与个性规则,完整校验与乐观锁 |
|
||
| GET /effective-rule?... | 返回生效规则及被覆盖层,用于编辑预览 |
|
||
| GET /alerts;GET /alerts/:id | 历史、活动及详情、过滤、分页 |
|
||
| GET /notification-summary | 轻量未读活动事件/异常维度数、更新时间,不聚合原始消息 |
|
||
| POST /alerts/:id/read | 个人幂等标记已读,不改变业务恢复状态 |
|
||
|
||
响应必须区分`rate=null`、`sample_insufficient`、`observing`、`stale`、`error`,不能统一0。越权资源返回一致404/403策略;后端从会话确定访问范围,不能相信前端tenantId。监控查看、阈值修改、通道纳管、消息详情分别校验权限,配置写入与版本审计在事务中完成。分页上限建议100,历史时间范围有限,错误明确返回而非静默成功。
|
||
|
||
## 10. 实施拆分与验收清单
|
||
|
||
### 10.1 分阶段建议
|
||
|
||
1. 先确认第2节口径与阈值,对真实代码/数据核验提交时间、回执匹配、分片合并和高峰规模。交付统计样本独立对账,不先接告警。
|
||
2. 实现兼容时间字段、独立投影/桶/快照,影子运行并与独立SQL按ID比对;监控关闭时不改变发送行为。完成容量和故障演练后才开启有限纳管。
|
||
3. 实现三页签、通用与个性规则、通道新建/复制提示,接预警中心轻量摘要和事件生命周期;先灰度一个测试范围再扩展。
|
||
4. 同步主需求、系统用例、技术设计及testing-progress;经授权提交、推送及部署,分别记录代码级与真实环境证据。
|
||
|
||
### 10.2 可直接转入系统用例的验收条目
|
||
|
||
| 编号 | 场景 | 预期 |
|
||
|---|---|---|
|
||
| SMR-001 | 5分钟边界、10分钟边界、跨天和时区 | 提交窗口左闭右开、UTC计算一致,无跨周期漏重 |
|
||
| SMR-002 | 三网通道含移动/联通/电信/未知号码 | 按消息运营商拆分;未知单列,不重复三次计数 |
|
||
| SMR-003 | 同业务短信换通道补发 | 通道按各尝试,应用签名按1条;t0不因补发重置 |
|
||
| SMR-004 | 长短信、重复/乱序/冲突回执 | 全必要分片同一有效尝试完整成功才计成功;幂等,负时延异常可追溯 |
|
||
| SMR-005 | 4.999/5.000/5.001秒以及20秒/1分/5分/20分边界 | 精确分类,不由显示四舍五入决定 |
|
||
| SMR-006 | 尚未成熟但已成功/已失败的样本 | 两者都观察中;不能只纳入提前成功者;N_h独立 |
|
||
| SMR-007 | N_h为0、99、100且最低100 | null、样本不足、可评估,零数据不显示100%或自动恢复 |
|
||
| SMR-008 | 最新30分钟,20分钟成熟段只有前10分钟 | 分子分母/观察中符合第4.3例子,不把新提交直接计为未到达 |
|
||
| SMR-009 | 正文含验证码、模板分类验证码但正文不含、不同租户同名签名 | 字面正文匹配;稳定ID归属和租户隔离,不混淆 |
|
||
| SMR-010 | 全部规则层同时匹配、重复修改、恢复继承 | 应用×签名>签名>应用>通用;整套规则覆盖、409冲突、来源可解释 |
|
||
| SMR-011 | 新建/复制成功后加入监控成功或失败 | 主创建只一次、加入幂等;失败保留新通道,复制不继承成员资格 |
|
||
| SMR-012 | 新建失败/无权限/关闭纳管弹窗 | 不误弹成功、不越权加入、后续可手动纳管 |
|
||
| SMR-013 | 一个维度三项低于阈值、连续重叠周期 | 一条活动事件、多命中指标;无重复角标刷屏 |
|
||
| SMR-014 | 已读、持续异常、恢复、再异常、样本不足 | 已读非恢复;充分数据连续恢复;再异常新未读;不足暂停评估 |
|
||
| SMR-015 | 回执Gateway及时但API处理迟到、规则变更 | 延迟/回算有revision;保留原告警与修正原因,不伪称终端时延 |
|
||
| SMR-016 | 投影Worker重启、多实例抢占、数据库/Redis故障 | 检查点可恢复、幂等;监控显示降级,业务发送链无新增依赖阻断 |
|
||
| SMR-017 | 长事务晚提交、游标跨越、已扫描Inbox后匹配 | 重叠读取+待匹配集合+有界对账恢复,不永久漏统 |
|
||
| SMR-018 | 预警中心接口失败、权限变化、点告警深链接 | 其他域不清零,来源状态明确;同作用域计数与列表一致 |
|
||
| SMR-019 | 三尺寸、首次进入、刷新、筛选、弹窗失败与未保存离开 | 无页面级意外溢出,正文可读、Footer可见,表单状态保留 |
|
||
| SMR-020 | 高峰/高基数/长短信与监控开启关闭对照 | 按第8.5预算出真实CPU/IO/延迟/队列/存储报告,不用构建成功代替 |
|
||
| SMR-021 | 旧数据缺时间、不确定发包、不支持回执 | 单列不可评估和完整性,不伪造指标或混入健康样本 |
|
||
| SMR-022 | 旧功能入口与跨业务提醒分组 | 保留运行概况/最近事件入口,新告警只进预警中心,不污染报备和待审核 |
|
||
| SMR-023 | 固定窗口尾部与补齐任务 | 12:29:59提交的行业/验证码短信必须进入12:30窗口的12:31定稿;初评/定稿不重复计告警次数,旧定稿不覆盖新状态 |
|
||
|
||
## 11. 原型文件与本轮验证边界
|
||
|
||
参见[原型目录](prototypes/sending-monitor-20260906/README.md),PNG便于预览,SVG用于后续修改。所有表格为示例数据;正文未展示短信、手机号或验证码。原型是需求交流材料,不接后端,不可作为业务验收证据。
|
||
|
||
本轮已核验文档相对链接、Markdown代码块、空白、统计公式示例、绘制脚本语法、七组PNG/SVG尺寸及可解析性,并逐图检查文字与布局;文件范围仅本文及专属原型目录。没有真实API/数据库/Redis功能测试或性能压测。阈值、兜底范围、提交计时起点及容量预算必须在实施前评审,不能依据示例图直接启用告警。
|
||
|
||
## 12. 实施决策与验收边界(2026-09-06)
|
||
|
||
用户已确认默认阈值留空,由运营后续配置;任何原型阈值均不自动启用。前三节旧记录保留为设计阶段证据,不代表当前实施状态。
|
||
|
||
新增 Gateway 实际写出时间、时间来源及真实上游回执请求标记,随已有结果和分片耐久事件传递;API 持久化到尝试/分片,回执新增 gatewayReceivedAt 区分真实 Gateway 接收时间与 API 缺省时间。客户端是否要求下游回执不能代替上游实际请求标记。现有 Inbox 的 matchedSubmitRecordId 尚未写入,投影使用已匹配业务消息、通道和网关消息号关联,遇到尝试重号拒绝混合。
|
||
|
||
独立 Worker 使用最多2个 PostgreSQL 连接、单执行槽、数据库排他租约;提交及回执各自保留重叠游标,另有72小时有界对账,脏分钟只重算所属固定窗口/最多3个兜底窗口,调度队列与投影原子提交。指标读取成熟分钟桶加毫秒边界事实,不按页面刷新扫描业务大表。
|
||
|
||
事实保留期本次采用72小时(第8节2小时是原建议),以保证迟到修改能替换原贡献、不会在删除事实后把旧桶重建成局部样本;分钟7天、快照30天、关闭告警90天。新增表不存短信正文/手机号。需要以真实峰值容量预算再优化事实压缩/冷热分层;当前不得据此宣称500TPS下预算达标。真实短信压测未获授权,只使用隔离数据库样本验证统计和查询成本。
|
||
|
||
纳管范围使用不可变版本,按窗口评估时刻解析;以后移除/重新加入不改写旧统计。当前API规则按type+scope通过POST完整保存(version乐观锁),不另外提供重复的PUT更新入口。新Worker健康异常通过发送监控数据延迟和预警中心不可用说明展示;监控性能指标接Prometheus和真实峰值对照尚未验收。
|
||
|
||
## 13. 整体兜底规则管理交互改造(2026-09-06)
|
||
|
||
状态:用户已授权实施、提交、推送并分别发布测试和预生产。替代第5.3节配置操作方式,统计口径、整套覆盖顺序和下一周期生效规则保持。
|
||
|
||
- 阈值设置分“通用规则”和“个性化规则”页签。后者为可搜索、分页的规则列表,展示企业/应用/签名名称、覆盖类型、阈值摘要、状态、生效时间,提供新增覆盖、编辑和恢复继承;不以内部ID作为主要展示。
|
||
- 新增覆盖默认应用级;支持应用、签名、应用×签名。应用选择器直接搜索“企业·应用”;签名级先选企业,组合级签名限定该应用。搜索和分页放入对应下拉框,选中持续显示名称;上级变化清空下级,未保存变更先确认。
|
||
- 编辑器与列表在同一弹窗切换,已有规则范围锁定;新增重复范围提示编辑已有规则。新规则按实际继承来源预填整套配置,没有来源则保持空值,不从原型填阈值。异步加载失败阻止提交、提供重试;迟到请求不能覆盖已修改草稿。
|
||
- 表单分适用范围、告警阈值、触发与恢复三组;保存按钮防重、字段就近校验、失败保留草稿、409允许显式重新加载。保存成功返回列表并保留筛选,显示真实版本及下一周期生效时间。切换页签、返回列表、关闭和刷新保护未保存内容。
|
||
- 停用仍保留该层覆盖;恢复继承移除该层覆盖,使用数据库已保存配置和version,不受编辑草稿必填校验干扰。确认说明剩余规则匹配顺序,具体应用×签名可查看准确匹配链;没有下层规则明确不告警,更具体范围仍按自身规则匹配。恢复仍通过版本记录/审计事务生效,不物理删除历史。
|
||
- 新增受既有管理员授权保护的规则管理分页、对象远程搜索、编辑上下文和恢复继承API;保留原rules/options/effective-rule接口兼容其他使用者。返回名称及对象状态、当前生效版本/待生效版本/服务器时间;历史已删除对象保留名称或明确占位,不进入新增选项。使用参数绑定、分页上限和确定性排序;新增查询不进入发送热路径,不改变表结构、Redis或Worker计算。
|
||
- 样式归sending-monitor组件目录,由所有者import,不修改历史CSS模块或公共Select。验收覆盖真实API/PG持久化、三种范围及跨企业校验、继承/停用差异、重复/并发409、异步及失败、三尺寸和历史对象;发布仅重建前后端并重启API,其他服务按实际兼容检查保留。預生产缺少有效登录入口时如实保留登录后验收缺口,不擅自新增账号。
|