feat: 实现 IoT 卡轮询系统(支持千万级卡规模)
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m35s

实现功能:
- 实名状态检查轮询(可配置间隔)
- 卡流量检查轮询(支持跨月流量追踪)
- 套餐检查与超额自动停机
- 分布式并发控制(Redis 信号量)
- 手动触发轮询(单卡/批量/条件筛选)
- 数据清理配置与执行
- 告警规则与历史记录
- 实时监控统计(队列/性能/并发)

性能优化:
- Redis 缓存卡信息,减少 DB 查询
- Pipeline 批量写入 Redis
- 异步流量记录写入
- 渐进式初始化(10万卡/批)

压测工具(scripts/benchmark/):
- Mock Gateway 模拟上游服务
- 测试卡生成器
- 配置初始化脚本
- 实时监控脚本

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-05 17:32:44 +08:00
parent b11edde720
commit 931e140e8e
104 changed files with 16883 additions and 87 deletions

View File

@@ -0,0 +1,159 @@
## ADDED Requirements
### Requirement: 创建轮询配置
系统 SHALL 允许管理员创建轮询配置,指定卡匹配条件(卡状态、卡类型、运营商)和检查间隔(实名检查、卡流量检查、套餐流量检查),以及优先级。
#### Scenario: 创建基本轮询配置
- **WHEN** 管理员提交创建轮询配置请求包含配置名称、卡状态条件not_real_name、实名检查间隔30秒、优先级10
- **THEN** 系统创建轮询配置并返回配置ID和详情
#### Scenario: 创建带运营商筛选的配置
- **WHEN** 管理员创建轮询配置指定卡状态条件not_real_name、运营商ID1-中国移动、实名检查间隔60秒
- **THEN** 系统创建配置,该配置只匹配中国移动的未实名卡
#### Scenario: 创建带卡类型筛选的配置
- **WHEN** 管理员创建轮询配置指定卡业务类型industry-行业卡、卡流量检查间隔1800秒、禁用实名检查
- **THEN** 系统创建配置,行业卡不参与实名检查,只参与流量检查
#### Scenario: 配置名称重复
- **WHEN** 管理员创建轮询配置,配置名称与已有配置重复
- **THEN** 系统返回错误,提示配置名称已存在
#### Scenario: 检查间隔无效
- **WHEN** 管理员创建轮询配置,检查间隔小于 10 秒或大于 86400 秒24小时
- **THEN** 系统返回错误提示检查间隔超出有效范围10-86400秒
### Requirement: 查询轮询配置列表
系统 SHALL 提供轮询配置列表查询接口,支持分页和状态筛选。
#### Scenario: 查询所有配置
- **WHEN** 管理员请求查询轮询配置列表,不指定筛选条件
- **THEN** 系统返回所有轮询配置列表按优先级升序排序包含配置ID、名称、卡匹配条件、检查间隔、优先级、状态
#### Scenario: 查询启用的配置
- **WHEN** 管理员请求查询轮询配置列表,筛选条件为状态=启用
- **THEN** 系统只返回状态为启用的配置
#### Scenario: 分页查询
- **WHEN** 管理员请求查询轮询配置列表指定分页参数page=2, page_size=10
- **THEN** 系统返回第二页的配置列表,每页最多 10 条
### Requirement: 查询单个轮询配置详情
系统 SHALL 提供查询单个轮询配置详情的接口,包含完整的配置信息和匹配卡数量统计。
#### Scenario: 查询配置详情
- **WHEN** 管理员请求查询配置ID为 1 的详情
- **THEN** 系统返回配置的完整信息,包括配置名称、描述、卡匹配条件、检查间隔、优先级、状态、创建时间、更新时间
#### Scenario: 查询不存在的配置
- **WHEN** 管理员请求查询不存在的配置ID
- **THEN** 系统返回错误,提示配置不存在
#### Scenario: 包含匹配卡数量
- **WHEN** 管理员请求查询配置详情,请求参数包含 include_stats=true
- **THEN** 系统返回配置信息,额外包含当前匹配该配置的卡数量
### Requirement: 更新轮询配置
系统 SHALL 允许管理员更新轮询配置,修改检查间隔、优先级、启用状态等参数,更新后自动影响匹配的卡。
#### Scenario: 更新检查间隔
- **WHEN** 管理员更新配置,将实名检查间隔从 30 秒修改为 60 秒
- **THEN** 系统更新配置,所有匹配该配置的卡的下次实名检查时间重新计算
#### Scenario: 更新优先级
- **WHEN** 管理员更新配置优先级,从 10 修改为 5
- **THEN** 系统更新配置,重新匹配所有卡(因为优先级影响匹配顺序)
#### Scenario: 修改卡匹配条件
- **WHEN** 管理员更新配置,将卡状态条件从 not_real_name 修改为 real_name
- **THEN** 系统更新配置,重新匹配所有卡,原匹配该配置的卡不再匹配,原不匹配的卡可能匹配
#### Scenario: 禁用某项检查
- **WHEN** 管理员更新配置禁用实名检查real_name_check_enabled=false
- **THEN** 系统更新配置,所有匹配该配置的卡从实名检查队列移除
#### Scenario: 更新不存在的配置
- **WHEN** 管理员尝试更新不存在的配置ID
- **THEN** 系统返回错误,提示配置不存在
### Requirement: 删除轮询配置
系统 SHALL 允许管理员删除轮询配置(软删除),删除后匹配该配置的卡将从轮询队列移除。
#### Scenario: 删除未使用的配置
- **WHEN** 管理员删除一个没有匹配卡的配置
- **THEN** 系统软删除配置,标记 deleted_at 字段
#### Scenario: 删除正在使用的配置
- **WHEN** 管理员删除一个有 1000 张卡匹配的配置
- **THEN** 系统软删除配置,所有匹配该配置的卡从轮询队列移除,卡缓存中的 matched_config_id 清空
#### Scenario: 删除后卡重新匹配
- **WHEN** 管理员删除配置后,卡失去匹配配置
- **THEN** 系统自动为卡重新匹配其他可用配置(按优先级),如果没有匹配配置,卡不参与轮询
#### Scenario: 删除不存在的配置
- **WHEN** 管理员尝试删除不存在的配置ID
- **THEN** 系统返回错误,提示配置不存在
### Requirement: 启用/禁用轮询配置
系统 SHALL 提供快捷接口启用或禁用轮询配置,禁用后匹配该配置的卡不再参与轮询。
#### Scenario: 禁用配置
- **WHEN** 管理员禁用配置ID为 1 的配置
- **THEN** 系统更新配置状态为禁用status=2所有匹配该配置的卡从轮询队列移除
#### Scenario: 启用配置
- **WHEN** 管理员启用配置ID为 1 的配置
- **THEN** 系统更新配置状态为启用status=1重新匹配卡并加入轮询队列
#### Scenario: 禁用后卡重新匹配其他配置
- **WHEN** 管理员禁用优先级为 10 的配置A该配置有 1000 张卡匹配
- **THEN** 系统为这 1000 张卡重新匹配其他配置(如优先级为 20 的配置B卡使用新配置的检查间隔
### Requirement: 配置匹配规则验证
系统 SHALL 验证轮询配置的匹配规则,确保配置逻辑正确。
#### Scenario: 实名检查不适用于行业卡
- **WHEN** 管理员创建配置,卡类型为 industry行业卡启用实名检查
- **THEN** 系统返回警告,提示行业卡无需实名检查,建议禁用实名检查
#### Scenario: 至少启用一种检查
- **WHEN** 管理员创建配置,禁用所有检查(实名、流量、套餐都为 false
- **THEN** 系统返回错误,提示至少启用一种检查类型
#### Scenario: 优先级唯一性建议
- **WHEN** 管理员创建配置,优先级与已有配置相同
- **THEN** 系统返回警告,提示优先级重复可能导致匹配顺序不确定,建议使用唯一优先级