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>
8.0 KiB
8.0 KiB
ADDED Requirements
Requirement: 并发配置初始化
系统 SHALL 在启动时从数据库加载并发配置到 Redis。
Scenario: 首次启动加载配置
- WHEN Worker 进程启动,Redis 中没有并发配置
- THEN 系统从 tb_polling_concurrency_config 表读取所有配置,写入 Redis(polling:concurrency:config:{type})
Scenario: 配置已存在则跳过
- WHEN Worker 进程启动,Redis 中已有并发配置
- THEN 系统跳过初始化,使用 Redis 中的配置(避免覆盖运行时修改)
Scenario: 数据库无配置则使用默认值
- WHEN 数据库中没有并发配置记录
- THEN 系统使用默认值(实名检查:50、流量检查:50、套餐检查:30、停复机:10),写入 Redis
Requirement: 并发信号量获取
系统 SHALL 在任务执行前获取 Redis 信号量,控制并发数。
Scenario: 获取信号量成功
- WHEN 实名检查任务开始,当前并发数为 30,最大并发数为 50
- THEN 系统执行 INCR polling:concurrency:current:realname,返回值 31,小于等于 50,获取成功
Scenario: 并发已满拒绝执行
- WHEN 实名检查任务开始,当前并发数为 50,最大并发数为 50
- THEN 系统执行 INCR 返回值 51,大于 50,立即 DECR 归还,任务返回 SkipRetry
Scenario: 信号量获取失败重试
- WHEN 任务在并发已满时被拒绝
- THEN 系统不重试,直接返回,等待下次调度周期(10秒后)再次尝试
Scenario: Redis 连接失败
- WHEN INCR 操作因 Redis 连接失败
- THEN 系统记录错误日志,任务失败,不执行业务逻辑
Requirement: 并发信号量释放
系统 SHALL 在任务完成后释放 Redis 信号量。
Scenario: 任务成功完成释放
- WHEN 实名检查任务成功完成
- THEN 系统执行 DECR polling:concurrency:current:realname,释放信号量
Scenario: 任务失败也释放
- WHEN 实名检查任务因 Gateway 超时失败
- THEN 系统在 defer 中执行 DECR,确保信号量释放
Scenario: Panic 恢复后释放
- WHEN 任务执行中发生 panic
- THEN 系统在 recover 后执行 DECR,防止信号量泄漏
Scenario: DECR 失败记录日志
- WHEN DECR 操作失败
- THEN 系统记录错误日志,包含 task_type、task_id,便于排查信号量计数异常
Requirement: 动态调整并发数
系统 SHALL 支持通过管理接口实时调整最大并发数,无需重启 Worker。
Scenario: 管理员提高并发数
- WHEN 管理员调用接口,将实名检查最大并发数从 50 提高到 80
- THEN 系统更新 Redis(SET polling:concurrency:config:realname 80),更新数据库配置表
Scenario: 管理员降低并发数
- WHEN 管理员调用接口,将流量检查最大并发数从 50 降低到 30
- THEN 系统更新 Redis 和数据库,当前正在执行的任务继续,新任务受新限制
Scenario: 调整后立即生效
- WHEN 并发数调整完成
- THEN 系统下次任务获取信号量时,使用新的最大并发数判断
Scenario: 并发数无效值校验
- WHEN 管理员尝试设置并发数为 0 或负数
- THEN 系统返回错误,提示并发数必须大于 0
Scenario: 并发数过大警告
- WHEN 管理员尝试设置并发数大于 200
- THEN 系统返回警告,提示过高并发可能打爆 Gateway,建议值范围 10-100
Requirement: 查询并发状态
系统 SHALL 提供接口查询各类型任务的并发配置和实时并发数。
Scenario: 查询所有类型并发状态
- WHEN 管理员请求查询并发状态
- THEN 系统返回所有类型(realname、carddata、package、stoprestart)的最大并发数和当前并发数
Scenario: 查询单个类型并发状态
- WHEN 管理员请求查询实名检查并发状态
- THEN 系统返回 max_concurrency=50、current_concurrency=30、usage_rate=60%
Scenario: 并发数异常检测
- WHEN 查询并发状态,发现当前并发数大于最大并发数
- THEN 系统返回警告标志,提示可能存在信号量泄漏
Scenario: 长时间满载告警
- WHEN 查询并发状态,某类型并发数连续 5 分钟保持满载(usage_rate=100%)
- THEN 系统返回建议,提示可能需要提高并发数或优化任务性能
Requirement: 分类型并发控制
系统 SHALL 为不同任务类型(实名检查、流量检查、套餐检查、停复机)独立控制并发数。
Scenario: 实名检查独立控制
- WHEN 实名检查任务获取信号量
- THEN 系统使用 polling:concurrency:config:realname 和 polling:concurrency:current:realname
Scenario: 流量检查独立控制
- WHEN 流量检查任务获取信号量
- THEN 系统使用 polling:concurrency:config:carddata 和 polling:concurrency:current:carddata
Scenario: 套餐检查独立控制
- WHEN 套餐检查任务获取信号量
- THEN 系统使用 polling:concurrency:config:package 和 polling:concurrency:current:package
Scenario: 停复机独立控制
- WHEN 停复机任务获取信号量
- THEN 系统使用 polling:concurrency:config:stoprestart 和 polling:concurrency:current:stoprestart
Scenario: 互不影响
- WHEN 实名检查并发满载(50/50),流量检查并发正常(30/50)
- THEN 流量检查任务仍然可以正常获取信号量并执行,不受实名检查影响
Requirement: 并发配置持久化
系统 SHALL 将并发配置变更持久化到数据库。
Scenario: 更新配置同步数据库
- WHEN 管理员调整并发数
- THEN 系统先更新 Redis,再更新数据库(UPDATE tb_polling_concurrency_config SET max_concurrency=? WHERE task_type=?)
Scenario: 数据库更新失败回滚
- WHEN Redis 更新成功,但数据库更新失败
- THEN 系统回滚 Redis 配置到原值,返回错误
Scenario: 启动时以数据库为准
- WHEN Worker 进程重启,Redis 和数据库配置不一致
- THEN 系统以数据库配置为准,覆盖 Redis
Requirement: 并发监控统计
系统 SHALL 记录并发使用情况的监控统计。
Scenario: 记录峰值并发数
- WHEN 每次任务获取信号量成功
- THEN 系统更新 Redis Hash(polling:stats:concurrency:{type}),记录当前并发数,如果大于历史峰值则更新峰值
Scenario: 记录并发拒绝次数
- WHEN 任务因并发已满被拒绝
- THEN 系统增加 Redis Hash 的 reject_count_1h 计数
Scenario: 每小时重置统计
- WHEN 每小时整点
- THEN 系统重置 reject_count_1h,保留 peak_concurrency(持续统计)
Requirement: 信号量计数修复
系统 SHALL 提供接口修复异常的信号量计数。
Scenario: 手动重置计数器
- WHEN 管理员发现并发计数异常(如泄漏导致一直为 50 无法下降)
- THEN 管理员调用接口,系统将 polling:concurrency:current:{type} 重置为 0
Scenario: 自动检测修复
- WHEN 系统定期检查(每 5 分钟),发现当前并发数长时间不变且无任务执行
- THEN 系统记录警告日志,建议管理员检查并手动修复
Scenario: 修复操作记录日志
- WHEN 执行信号量重置
- THEN 系统记录操作日志,包含操作人、重置前值、重置后值、原因
Requirement: 日志记录
系统 SHALL 记录并发控制的关键操作日志。
Scenario: 记录并发满载日志
- WHEN 任务因并发已满被拒绝
- THEN 系统记录 Info 日志,包含 task_type、current_concurrency、max_concurrency
Scenario: 记录配置变更日志
- WHEN 管理员调整并发数
- THEN 系统记录 Info 日志,包含 task_type、old_value、new_value、operator
Scenario: 记录信号量异常日志
- WHEN DECR 失败或检测到计数异常
- THEN 系统记录 Error 日志,包含详细上下文