All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m33s
- 新增网关限流:按本系统运营商账户(卡 carrier_id)→ 限流组 → 操作限制每秒请求数,每次 HTTP 尝试计量,默认限流、仅后台人工点击/通道阈值/自动续费/手动刷新豁免;支持只统计与拦截两种模式,默认只统计 - Asynq 遇限流不计失败、固定短延迟重试;轮询任务与停复机业务重试遇限流短延迟重排 - 停机、复机不再使用网关内部重试,只发一次请求 - 网关返回结构化错误;新增上游错误分类规则表与测试接口 - 新增按月分区的停复机记录表:系统自动停复机只写记录,不再写统一审计与集成日志;普通轮询查询不再写集成日志 - 新增限流组、错误分类、停复机记录、按账户调用统计与枚举后台接口 - 迁移 000243~000246;同步 OpenSpec 提案(含后续 6 个 change)与技术方案、工程约束
28 lines
2.3 KiB
Markdown
28 lines
2.3 KiB
Markdown
## Context
|
||
|
||
依据 `docs/engineering/轮询按运营商账户限流技术方案.md` 第一部分第 6 节、第四部分"保护期整套机制"。
|
||
|
||
现状:后台设备停复机设置 `protect:device:{id}:stop|start`(1 小时,互斥,`internal/service/device/service.go:1506,1663`);保护期内拒绝相反人工操作;`polling:protect` 轮询(`internal/task/polling_protect_handler.go`)方向不一致时 `ForceStopCard` / `ForceStartCard`;自动停复机 `EvaluateAndAct` 不看保护期,造成反复翻转。`ProtectCheckSkipsForRealname`(`stop_resume_unified.go`)仅保护期轮询使用。资产 DTO 有 `device_protect_status`(`asset_dto.go:38,144`、`client_asset_dto.go:75`)。
|
||
|
||
## Goals / Non-Goals
|
||
|
||
**Goals:** 删除保护期的设置、检查、轮询与展示逻辑;不破坏现有客户端;数据库只加不删。
|
||
|
||
**Non-Goals:** 不改停复机业务规则(第 4、6 个 Change);不删 `protect_period` 常量与历史数据;不删数据库列。
|
||
|
||
## Decisions
|
||
|
||
1. **字段保留、固定返回 `none`**:直接删字段会让读取该字段的老版本小程序出错;固定值兼容成本最低。备选"字段 omitempty 后不返回":老客户端读不到同样可能出错,放弃。
|
||
2. **数据库列只改注释**:遵循"数据库只加不删";`protect_check_interval`、`last_protect_check_at` 列注释标记已废弃,代码中去掉读写。
|
||
3. **存量 Redis 保护期 key 不清理**:TTL 只有 1 小时,上线后自然过期;代码不再读取,即使残留也无影响。
|
||
4. **Asynq 中已排队的 `polling:protect` 任务**:保留一个空处理函数直接返回成功一个发布周期,避免"未注册任务类型"错误堆积,下一次发布再移除;或上线前确认队列为空。选择保留空处理函数,更稳妥。
|
||
|
||
## Risks / Trade-offs
|
||
|
||
- [运营依赖保护期防止误操作] → 已定"规则优先、人工停机无豁免",需要保持停机的关闭轮询(第 7 个 Change 提供批量操作)。
|
||
- [前端仍展示保护期] → 固定 `none` 时前端显示"无",不报错;前端随后去掉展示。
|
||
|
||
## Migration Plan
|
||
|
||
1. 迁移只改列注释。2. 测试环境验证后由维护者发布生产。3. 回退:代码回退即可恢复保护期逻辑,数据库无需回退。
|