# 轮询系统性能调优指南 ## 千万卡规模优化方案 ### 1. 调度器优化 当前配置存在瓶颈:每次只取 1000 张卡,每 10 秒调度一次,每分钟最多处理 6000 张卡。 **优化方案**: ```go // 修改 scheduler.go 中的 processTimedQueue cardIDs, err := s.redis.ZRangeByScore(ctx, queueKey, &redis.ZRangeBy{ Min: "-inf", Max: formatInt64(now), Count: 10000, // 从 1000 提高到 10000 }).Result() ``` 调整调度间隔: ```go func DefaultSchedulerConfig() *SchedulerConfig { return &SchedulerConfig{ ScheduleInterval: 5 * time.Second, // 从 10 秒改为 5 秒 // ... } } ``` 优化后:每分钟可处理 12 万张卡 ### 2. 并发控制优化 修改 `scripts/init_polling_config.sql`: ```sql -- 千万卡规模的并发配置 INSERT INTO tb_polling_concurrency_config (task_type, max_concurrency, description) VALUES ('realname', 500, '实名检查并发数'), ('carddata', 1000, '流量检查并发数'), ('package', 500, '套餐检查并发数'), ('stop_start', 100, '停复机操作并发数'); ``` ### 3. Worker 多实例部署 部署多个 Worker 实例分担负载: ```yaml # docker-compose.yml 示例 services: worker-1: image: junhong-cmp-worker environment: - WORKER_ID=1 worker-2: image: junhong-cmp-worker environment: - WORKER_ID=2 worker-3: image: junhong-cmp-worker environment: - WORKER_ID=3 ``` 注意:只需一个实例运行调度器,其他实例只处理任务。 ### 4. 检查间隔优化 根据业务需求调整检查间隔,减少不必要的检查: | 卡状态 | 当前间隔 | 建议间隔 | 说明 | |--------|---------|---------|------| | 未实名 | 60 秒 | 300 秒 | 实名状态不会频繁变化 | | 已实名 | 3600 秒 | 86400 秒 | 已实名只需每天检查一次 | | 已激活流量 | 1800 秒 | 3600 秒 | 每小时检查一次足够 | 这样可以大幅减少检查次数: - 原方案:1000 万次/小时 - 优化后:约 100 万次/小时 ### 5. 初始化优化 使用 Pipeline 批量写入 Redis: ```go // 优化 initCardPolling,使用 Pipeline func (s *Scheduler) initCardsBatch(ctx context.Context, cards []*model.IotCard) error { pipe := s.redis.Pipeline() for _, card := range cards { config := s.MatchConfig(card) if config == nil { continue } // 批量 ZADD nextTime := s.calculateNextCheckTime(card, config) pipe.ZAdd(ctx, queueKey, redis.Z{Score: float64(nextTime), Member: card.ID}) // 批量 HSET pipe.HSet(ctx, cacheKey, cardData) } _, err := pipe.Exec(ctx) return err } ``` 优化效果:减少 Redis 往返次数,初始化时间从 150 秒降至 30-50 秒 ### 6. 数据库索引优化 确保以下索引存在: ```sql -- 用于渐进式初始化的游标分页 CREATE INDEX IF NOT EXISTS idx_iot_card_id_asc ON tb_iot_card(id ASC) WHERE deleted_at IS NULL; -- 用于条件筛选 CREATE INDEX IF NOT EXISTS idx_iot_card_polling ON tb_iot_card(enable_polling, real_name_status, activation_status, card_category); ``` ### 7. Redis 配置优化 ```conf # redis.conf maxmemory 8gb maxmemory-policy allkeys-lru # 连接池优化 tcp-keepalive 300 timeout 0 ``` ### 8. 监控告警阈值 千万卡规模的告警阈值建议: ```sql INSERT INTO tb_polling_alert_rule (rule_name, metric_type, task_type, threshold, comparison, alert_level) VALUES ('队列积压告警', 'queue_size', 'polling:realname', 100000, 'gt', 'critical'), ('失败率告警', 'failure_rate', 'polling:realname', 10, 'gt', 'warning'), ('延迟告警', 'avg_wait_time', 'polling:carddata', 3600, 'gt', 'warning'); ``` --- ## 容量规划 | 规模 | Worker 数 | Redis 内存 | 并发总数 | 预估 QPS | |------|----------|-----------|---------|---------| | 100 万卡 | 2 | 512MB | 200 | 1000 | | 500 万卡 | 4 | 2GB | 500 | 3000 | | 1000 万卡 | 8 | 4GB | 1000 | 5000 | | 2000 万卡 | 16 | 8GB | 2000 | 10000 | ## 压测建议 1. 使用 `wrk` 或 `vegeta` 对 API 进行压测 2. 使用脚本批量创建测试卡验证初始化性能 3. 监控 Redis 内存和 CPU 使用率 4. 监控数据库连接池和查询延迟 ```bash # API 压测示例 wrk -t12 -c400 -d30s http://localhost:3000/api/admin/polling-stats ```