## 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 日志,包含详细上下文