Files
junhong_cmp_fiber/openspec/changes/add-stop-resume-command-queue/tasks.md
邹进 42e881576d
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m33s
feat: 卡网关按运营商账户限流并记录停复机调用
- 新增网关限流:按本系统运营商账户(卡 carrier_id)→ 限流组 → 操作限制每秒请求数,每次 HTTP 尝试计量,默认限流、仅后台人工点击/通道阈值/自动续费/手动刷新豁免;支持只统计与拦截两种模式,默认只统计
- Asynq 遇限流不计失败、固定短延迟重试;轮询任务与停复机业务重试遇限流短延迟重排
- 停机、复机不再使用网关内部重试,只发一次请求
- 网关返回结构化错误;新增上游错误分类规则表与测试接口
- 新增按月分区的停复机记录表:系统自动停复机只写记录,不再写统一审计与集成日志;普通轮询查询不再写集成日志
- 新增限流组、错误分类、停复机记录、按账户调用统计与枚举后台接口
- 迁移 000243~000246;同步 OpenSpec 提案(含后续 6 个 change)与技术方案、工程约束
2026-10-24 15:06:41 +09:00

62 lines
4.9 KiB
Markdown
Raw 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. 前置确认
- [ ] 0.1 确认第 1、4、5 个 Change 已上线。
## 1. 迁移与配置
- [ ] 1.1 新增成对迁移:`tb_system_config` 插入 `polling.stop_resume_queue_enabled`(默认 false)、结果未知告警阈值、停复机退避序列与告警阈值;注册受控系统配置项。
## 2. 统一判断与请求评估
- [ ] 2.1 抽出统一判断函数(暂停轮询按场景 → 停机条件 → 复机条件 → 通道阈值锁),`EvaluateAndAct`、`resumeSingleCard`、`resumeDeviceCards`、`ResumeCardIfStopped` 改为调用它。
- [ ] 2.2 新增"请求评估(卡或设备、场景、来源)"门面:开关开启时单卡生成指令、设备请求设备判断;关闭时走旧路径当场执行。
- [ ] 2.3 指令写入 Lua:覆盖并 `HINCRBY ver`、方向相反清零失败计数、放入卡所属账户 `stop_resume`。
## 3. 指令领取与执行
- [ ] 3.1 分发器在卡任务之前领取 `stop_resume`:清理过期 `sr_running`,领取数 = min(剩余 QPS, `sr_inflight_limit` − 执行中),校验 `sr_last_call` 推后,写 `sr_claim` 并记版本;开关开启后对全部账户领取。
- [ ] 3.2 NSQ `polling.stop_resume.{cid}` 专用消费者:核对 token、抢 `sr_exec`、续期。
- [ ] 3.3 执行器:按场景重新判断 → 写 `sr_last_call` → 调用一次网关(限流等待模式)→ 成功沿用现有回写与停复机记录;收尾按版本移除或保留。
- [ ] 3.4 结果未知:置待确认,确认延迟后先判断再查状态,按规则结束、重发或推后;查询失败不重发;连续未知达阈值告警。
- [ ] 3.5 失败分类处理:频率限制、终态(含自动关闭轮询)、已是目标状态、账户配置错误、临时故障与业务错误;停复机方向写入 `tb_polling_failure_alert`;指令不丢弃。
## 4. 设备维度判断
- [ ] 4.1 请求设备判断 Lua:`INCR eval_ver`、`SADD eval_scenes`、`ZADD LT device_eval:queue`。
- [ ] 4.2 分发与消费:抢 `device_eval:dispatch_lock` 领取,NSQ `polling.device_eval`;消费者抢 `eval_lock`(检查旧路径设备锁),读最新数据判断,为各卡写指令(记录场景)。
- [ ] 4.3 收尾:`SREM` 已处理场景,比较版本,变大则 score 设为当前时间再判断。
- [ ] 4.4 轮询路径不再使用 `RedisPollingDeviceOpLockKey`;人工设备停复机保持不变。
## 5. 自动入口改造
- [ ] 5.1 套餐步骤与 Outbox 三个卡观测消费者改为请求评估,不再同步调网关、不 sleep 重试。
- [ ] 5.2 `resumeAfterActivation`(4 处)、`reset_service.go:400`、`order/service.go:2196` 去掉 goroutine,事务提交后请求评估。
- [ ] 5.3 `refund/service.go` `stopAsset` 改为请求评估,写入成功即标记 `asset_reset`;`RecoverRefundPostProcessing` 只补偿"请求未写入"。
- [ ] 5.4 `package_activation_handler.go` 到期失效处:无其他有效主套餐时以"套餐到期"场景请求评估;接续激活路径不变。
- [ ] 5.5 `carrier/service.go` 实名管控修改后按 0 → 1、1 → 0 筛选受影响卡批量请求评估(设备卡按设备)。
## 6. 监控与接口
- [ ] 6.1 `/polling-stats` 按账户增加停复机队列长度、执行中、成功、失败、重试、结果未知数。
- [ ] 6.2 `/iot-cards/:id/polling-state` 返回当前指令(动作、原因、场景、版本、失败次数、待确认)。
- [ ] 6.3 重新生成接口文档。
## 7. 编译与规范校验
- [ ] 7.1 `gofmt -w`;`go build ./cmd/api ./cmd/worker` 通过。
- [ ] 7.2 `openspec validate add-stop-resume-command-queue` 与 `openspec doctor --json` 通过。
## 8. 测试环境验证(自动化测试为 N/A,按 ENG-TEST-001)
- [ ] 8.1 开关关闭:各入口行为与上线前一致。
- [ ] 8.2 指令覆盖:停机执行中写入复机指令,收尾后复机保留并在最小间隔后执行;无覆盖时指令被移除。
- [ ] 8.3 单卡最小重试间隔:间隔内不调用上游,score 推后到可调用时间。
- [ ] 8.4 结果未知:超时后确认延迟查状态,已是目标状态结束、否则按间隔重发、查询失败不重发。
- [ ] 8.5 失败分类:频率限制不计失败、终态不重试并按标记关闭轮询、已是目标状态按成功、持续失败告警且指令不丢。
- [ ] 8.6 设备判断:判断期间新请求使版本变化后再判断;到期与普通请求合并后场景保留;跨账户设备下各卡最终状态一致。
- [ ] 8.7 暂停轮询的卡:套餐到期与退款后停机执行一次;流量用完、激活、重置不自动停复机。
- [ ] 8.8 退款:上游终态卡退款后不再反复补发停机;资产后处理标记完成。
- [ ] 8.9 激活、重置、订单后复机经指令队列;流量重置日集中复机按账户 QPS 平滑。
- [ ] 8.10 实名管控 0 → 1、1 → 0 后受影响卡被批量评估且平滑执行。
- [ ] 8.11 开关开、关、再开:无重复停复机与漏停;旧路径设备锁持有时设备判断推后。