feat: 完善服务监控与下游重投

This commit is contained in:
hectorzhao
2026-08-14 17:21:29 +08:00
parent d30d9ea4d0
commit 1ef4380422
50 changed files with 1279 additions and 82 deletions
+12 -12
View File
@@ -1,8 +1,8 @@
# 下游投递后台批量重投任务设计与实现符合性审计
> 版本:V1.0<br>
> 版本:V1.1<br>
> 需求确认日期:2026-08-12<br>
> 文档整理日期:2026-08-13<br>
> 文档整理日期:2026-08-13;业务口径更新:2026-08-14<br>
> 适用页面:运营端 → 下游投递记录<br>
> 审计基线:当前工作区 `HEAD=67fee216162e638ba21004fcf87e7711facefb91`;本功能相关文件相对 HEAD 无未提交修改<br>
> 本文目的:还原 2026-08-12 已确认的设计口径,并将当前实现逐条映射到设计,不能以“已有代码”代替“符合设计”的结论。
@@ -27,9 +27,9 @@
1. 保留单条重投、当前页勾选批量重投,新增“按筛选条件重投”;投递记录分页支持每页 10/25/50 条。
2. 后台任务使用企业、应用、投递类型、状态、创建日期、关键词组成的筛选快照;页码和每页条数不属于任务范围。预检生成 `snapshotAt`,创建任务后产生的新记录不进入该任务。
3. 第一版后台任务允许 `pending``failed``unconfirmed``rejected`。不得批量重投客户端已确认的 `delivered`;处于 `awaiting_ack` 的记录不得并发重投。创建前展示真实命中数、可重投数、规则跳过数、状态分布,任务原因必填。
3. 后台任务允许 `pending``failed``unconfirmed``rejected``delivered`客户端已确认的 `delivered` 可按筛选快照再次投递,但必须醒目提示可能造成客户端重复处理;处于 `awaiting_ack` 的记录不得并发重投。创建前展示真实命中数、可重投数、规则跳过数、状态分布,任务原因必填。
4. 任务按企业应用分批执行,默认每个应用 10 条/秒。单条失败不阻断整批;连续失败达到 10 条,或 ACK 超时/拒绝达到安全阈值时,自动暂停。客户离线、已有链路等待 ACK 属于“等待”,不能记作“跳过”。
5. “跳过”严格表示本任务没有调用 Gateway。第一版跳过原因包括:执行前状态变化、被客户确认、已被其他任务处理、本任务已成功处理、不属于任务快照、应用或投递能力已停用、投递数据不完整、缺少原 Submit 映射。
5. “跳过”严格表示本任务没有调用 Gateway。跳过原因包括:执行前状态变化、创建任务后才被客户确认、已被其他任务处理、本任务已成功处理、不属于任务快照、应用或投递能力已停用、投递数据不完整、缺少原 Submit 映射。只有任务项冻结的原状态已是 `delivered` 时,才允许按已确认记录重投;其他状态在执行前收到迟到成功 ACK 时必须跳过。
6. 任务支持列表、详情、暂停、继续、终止。终止只影响尚未发送的任务项。任务项以 `taskId + deliveryId` 幂等;执行前原子认领并复核当前状态;API 重启后继续执行;已获得成功 ACK 的任务项不得再次发送。
7. 创建、暂停、继续、终止、自动暂停都必须写操作日志。任务必须使用真实 PostgreSQL、Gateway 和客户 ACK,不得使用 mock、静态数据或 localStorage。
@@ -54,7 +54,7 @@
1. 用户设置筛选条件,点击“按筛选条件重投”。
2. 后端在同一时点生成预检快照,返回:筛选条件、`snapshotAt`、筛选命中数、可重投数、规则跳过数、状态分布、涉及应用数、最早记录时间。
3. 弹窗明确告知第一版允许和禁止的状态
3. 弹窗明确告知允许 `pending/failed/unconfirmed/rejected/delivered`、禁止 `awaiting_ack`,并提示已确认记录再次投递可能造成客户端重复处理
4. 用户选择执行速度,填写不少于 5 个字的事故原因、工单号或处理说明。
5. 用户确认后,后端必须重新按预检的筛选快照和 `snapshotAt` 物化任务项,而不是使用前端传入的记录 ID 列表。
6. 创建成功后关闭弹窗,任务出现在任务列表,状态为“排队中”。
@@ -160,8 +160,8 @@
| 原因 | 判定 |
| --- | --- |
| 执行前状态已变化 | 已不属于允许重投状态,且不是等待 ACK/已确认 |
| 被客户确认 | 当前投递已`delivered` 且有效 ACK |
| 执行前状态已变化 | 已不属于允许重投状态,且不是等待 ACK |
| 创建任务后才被客户确认 | 任务项冻结原状态不`delivered`,执行前收到有效成功 ACK;避免把迟到确认变成未授权重复投递 |
| 已被其他任务处理 | 其他任务已认领、等待 ACK 或成功 |
| 本任务已成功处理 | 同任务项已有成功结果,重复扫描不得再调用 |
| 不属于任务快照 | 创建时间晚于 `snapshotAt` 或不再满足冻结范围 |
@@ -222,7 +222,7 @@
| --- | --- | --- |
| DRQ-001 | 筛选快照 | 企业、应用、类型、状态、日期、关键词均生效;分页无关;快照后新记录不进入 |
| DRQ-002 | 预检口径 | 命中、可重投、跳过和状态分布严格基于当前筛选条件 |
| DRQ-003 | 状态白名单 | 物化 `pending/failed/unconfirmed/rejected`;拒绝 `delivered/awaiting_ack` |
| DRQ-003 | 状态白名单 | 物化 `pending/failed/unconfirmed/rejected/delivered`;拒绝 `awaiting_ack`;仅冻结原状态为 `delivered` 的任务项可按已确认记录重投 |
| DRQ-004 | 每应用限速 | 多应用任务中每个应用独立达到配置速度,任意扫描重叠都不超速 |
| DRQ-005 | 客户离线 | 进入等待连接,不记失败或跳过,恢复连接后继续 |
| DRQ-006 | ACK 闭环 | 写出只进入等待;有效 ACK 成功;超时、拒绝、无效 Msg_Id 失败 |
@@ -250,13 +250,13 @@
| --- | --- | --- |
| 真实持久化 | 符合 | 已有任务表、任务项表和 migration,不使用前端本地状态代替任务 |
| 快照时间上限 | 基本符合 | 创建时按 `snapshotAt` 限制 `createdAt`,快照后记录不物化 |
| 后台状态白名单 | 符合 | `REPLAYABLE_STATUSES``pending/failed/unconfirmed/rejected` |
| 禁止后台任务处理已确认/等待 ACK 筛选 | 符合 | 创建接口明确拒绝 `delivered/awaiting_ack` |
| 后台状态白名单 | 符合 | `REPLAYABLE_STATUSES``pending/failed/unconfirmed/rejected/delivered` |
| 禁止后台任务处理等待 ACK 筛选 | 符合 | 创建接口明确拒绝 `awaiting_ack``delivered` 按已确认重复投递风险口径放行 |
| 原因校验 | 符合 | 少于 5 个字拒绝 |
| 任务项幂等 | 符合 | 数据库唯一约束 `taskId + deliveryId` |
| 执行前任务项认领 | 基本符合 | 通过 `status=queued` 的条件更新认领为 `processing` |
| 执行前复核 | 基本符合 | 重新查询投递、应用、payload 和其他任务状态 |
| 成功 ACK 不再发送 | 基本符合 | 已确认投递会跳过其他任务 `success` 也会阻止调用 |
| 成功 ACK 不再发送 | 基本符合 | `delivered` 快照项执行前才收到成功 ACK 时跳过其他任务 `success` 也会阻止调用;冻结原状态为 `delivered` 的项目属于运营明确授权的再次投递 |
| 人工控制 | 基本符合 | 已有暂停、继续、终止接口和页面按钮 |
| 核心操作日志 | 基本符合 | 创建、暂停、继续、终止、自动暂停均写日志 |
| 投递记录分页 | 符合 | 页面支持每页 10/25/50 条并回到第一页 |
@@ -279,7 +279,7 @@
| P1 | 自动化覆盖远低于设计风险 | 专项仅4个测试:预检计数、参数拒绝、活动任务冲突、已确认跳过 | 未覆盖限速、多应用、离线等待、ACK阈值、重启恢复、并发扫描、完整分页及所有审计动作 |
| P2 | 状态和详情表达偏内部化 | 任务列表/详情直接展示英文状态;任务详情只展示汇总和最近项 | 运营人员不易区分等待连接、等待外部ACK、任务写出等待ACK等状态 |
| P2 | 终止后的未处理数未进入常规汇总 | 终止把`queued`改为`unprocessed`,但任务汇总只保存成功/失败/跳过/等待 | 任务进度分子可能小于总数,页面没有单独解释未处理数量 |
| P2 | 已确认跳过原因存在口径混用 | `waiting_external_ack`最终由其他链路成功后记为“跳过:已由其他投递链路完成” | 可以接受为“本任务未调用Gateway”,但详情必须明确这是外部链路成功,不应让用户误以为业务未处理 |
| P2 | 外部 ACK 跳过原因存在口径混用 | `waiting_external_ack`最终由其他链路成功后记为“跳过:已由其他投递链路完成” | 可以接受为“本任务未调用Gateway”,但详情必须明确这是外部链路成功,不应让用户误以为业务未处理;这与冻结原状态为 `delivered` 的主动再次投递是两种情形 |
### 11.3 综合结论