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,213 @@
# 轮询系统部署文档
## 部署前准备
### 1. 环境要求
| 组件 | 最低版本 | 推荐版本 |
|------|----------|----------|
| PostgreSQL | 14.0 | 14+ |
| Redis | 6.0 | 6.0+ |
| Go | 1.21 | 1.21+ |
### 2. 配置检查
确保以下环境变量已配置:
```bash
# 数据库配置
JUNHONG_DATABASE_HOST
JUNHONG_DATABASE_PORT
JUNHONG_DATABASE_USER
JUNHONG_DATABASE_PASSWORD
JUNHONG_DATABASE_DBNAME
# Redis 配置
JUNHONG_REDIS_ADDRESS
JUNHONG_REDIS_PORT
JUNHONG_REDIS_PASSWORD
JUNHONG_REDIS_DB
```
## 部署步骤
### 步骤 1: 数据库迁移
```bash
# 检查迁移状态
make migrate-status
# 执行迁移
make migrate-up
# 验证迁移结果
psql $DATABASE_URL -c "SELECT tablename FROM pg_tables WHERE tablename LIKE 'tb_polling%' OR tablename LIKE 'tb_data_%';"
```
应该看到以下表:
- tb_polling_config
- tb_polling_concurrency_config
- tb_polling_alert_rule
- tb_polling_alert_history
- tb_data_cleanup_config
- tb_data_cleanup_log
- tb_polling_manual_trigger_log
- tb_data_usage_record
### 步骤 2: 初始化配置
```bash
# 执行初始化脚本
psql $DATABASE_URL -f scripts/init_polling_config.sql
# 验证初始化结果
psql $DATABASE_URL -c "SELECT config_name, priority, status FROM tb_polling_config ORDER BY priority;"
```
应该看到 5 条默认配置:
1. 未实名卡轮询 (priority: 10)
2. 行业卡轮询 (priority: 15)
3. 已实名卡轮询 (priority: 20)
4. 已激活卡轮询 (priority: 30)
5. 默认轮询配置 (priority: 100)
### 步骤 3: 验证 Redis 连接
```bash
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD ping
```
### 步骤 4: 编译应用
```bash
# 编译 API 服务
go build -o bin/api cmd/api/main.go
# 编译 Worker 服务
go build -o bin/worker cmd/worker/main.go
```
### 步骤 5: 灰度发布
**阶段 1: 单节点测试**
1. 先在一台 Worker 上部署新版本
2. 观察日志和监控指标 30 分钟
3. 确认无异常后继续
```bash
# 启动单个 Worker
./bin/worker &
# 检查日志
tail -f logs/worker.log | grep -i polling
```
**阶段 2: 滚动部署**
1. 逐步替换其他 Worker 节点
2. 每个节点间隔 5 分钟
3. 持续监控告警
### 步骤 6: 验证部署
```bash
# 检查调度器状态
curl http://localhost:3000/api/admin/polling-stats/init-progress
# 检查队列状态
curl http://localhost:3000/api/admin/polling-stats/queues
# 检查配置列表
curl http://localhost:3000/api/admin/polling-configs
```
## 配置调整
### 调整并发数
```bash
# 查看当前并发配置
curl http://localhost:3000/api/admin/polling-concurrency
# 调整实名检查并发数为 80
curl -X PUT http://localhost:3000/api/admin/polling-concurrency/realname \
-H "Content-Type: application/json" \
-d '{"max_concurrency": 80}'
```
### 调整轮询间隔
通过管理后台或 API 修改 tb_polling_config 表中的间隔配置。
## 回滚策略
### 快速回滚
1. 停止所有 Worker
2. 回滚代码版本
3. 执行数据库回滚(如需)
4. 重启 Worker
```bash
# 停止 Worker
pkill -f "bin/worker"
# 数据库回滚(如需)
make migrate-down STEP=9
# 清理 Redis 轮询相关数据
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD --scan --pattern "polling:*" | xargs redis-cli DEL
# 重新部署旧版本
./bin/worker-old &
```
### 数据清理
如果需要完全清理轮询系统数据:
```sql
-- 清理轮询配置
TRUNCATE TABLE tb_polling_config CASCADE;
TRUNCATE TABLE tb_polling_concurrency_config CASCADE;
TRUNCATE TABLE tb_polling_alert_rule CASCADE;
TRUNCATE TABLE tb_polling_alert_history CASCADE;
TRUNCATE TABLE tb_data_cleanup_config CASCADE;
TRUNCATE TABLE tb_data_cleanup_log CASCADE;
TRUNCATE TABLE tb_polling_manual_trigger_log CASCADE;
TRUNCATE TABLE tb_data_usage_record CASCADE;
```
```bash
# 清理 Redis
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD KEYS "polling:*" | xargs redis-cli DEL
```
## 常见问题
### Q1: Worker 启动缓慢
A: 检查数据库和 Redis 连接。正常情况下 Worker 应在 10 秒内完成启动。
### Q2: 队列积压严重
A: 增加并发数,或检查是否有 Gateway 接口响应慢的问题。
### Q3: 任务重复执行
A: 检查 Redis 连接稳定性,确保分布式锁正常工作。
### Q4: 迁移失败
A: 检查迁移日志,确认数据库权限。可能需要手动修复 schema_migrations 表。
## 监控建议
部署后建议配置以下监控:
1. **队列长度**polling:queue:* 的 ZCARD
2. **任务成功率**:统计 success/total 比率
3. **平均耗时**:关注 P95 和 P99
4. **并发使用率**current/max 比率
5. **告警触发数**tb_polling_alert_history 新增数