Files
junhong_cmp_fiber/scripts/benchmark/init_config.go
huang 931e140e8e
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m35s
feat: 实现 IoT 卡轮询系统(支持千万级卡规模)
实现功能:
- 实名状态检查轮询(可配置间隔)
- 卡流量检查轮询(支持跨月流量追踪)
- 套餐检查与超额自动停机
- 分布式并发控制(Redis 信号量)
- 手动触发轮询(单卡/批量/条件筛选)
- 数据清理配置与执行
- 告警规则与历史记录
- 实时监控统计(队列/性能/并发)

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

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:32:44 +08:00

157 lines
5.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//go:build ignore
// +build ignore
package main
import (
"fmt"
"log"
"os"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// PollingConfig 轮询配置
type PollingConfig struct {
ID uint `gorm:"primaryKey"`
ConfigName string `gorm:"column:config_name"`
CardCondition *string `gorm:"column:card_condition"`
CardCategory *string `gorm:"column:card_category"`
CarrierID *uint `gorm:"column:carrier_id"`
Priority int `gorm:"column:priority"`
RealnameCheckInterval *int `gorm:"column:realname_check_interval"`
CarddataCheckInterval *int `gorm:"column:carddata_check_interval"`
PackageCheckInterval *int `gorm:"column:package_check_interval"`
Status int `gorm:"column:status;default:1"`
Description string `gorm:"column:description"`
}
func (PollingConfig) TableName() string {
return "tb_polling_config"
}
// PollingConcurrencyConfig 并发控制配置
type PollingConcurrencyConfig struct {
ID uint `gorm:"primaryKey"`
TaskType string `gorm:"column:task_type"`
MaxConcurrency int `gorm:"column:max_concurrency"`
Description string `gorm:"column:description"`
}
func (PollingConcurrencyConfig) TableName() string {
return "tb_polling_concurrency_config"
}
func ptr[T any](v T) *T {
return &v
}
func main() {
fmt.Println("=== 初始化轮询配置 ===")
// 连接数据库
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
os.Getenv("JUNHONG_DATABASE_HOST"),
os.Getenv("JUNHONG_DATABASE_PORT"),
os.Getenv("JUNHONG_DATABASE_USER"),
os.Getenv("JUNHONG_DATABASE_PASSWORD"),
os.Getenv("JUNHONG_DATABASE_DBNAME"),
)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
log.Fatalf("连接数据库失败: %v", err)
}
fmt.Println("✓ 数据库连接成功")
// 清空现有配置
db.Exec("DELETE FROM tb_polling_config")
db.Exec("DELETE FROM tb_polling_concurrency_config")
fmt.Println("✓ 清空现有配置")
// 插入轮询配置
configs := []PollingConfig{
{
ConfigName: "未实名卡轮询",
CardCondition: ptr("not_real_name"),
Priority: 10,
RealnameCheckInterval: ptr(300), // 5分钟
Status: 1,
Description: "未实名卡每5分钟检查一次实名状态",
},
{
ConfigName: "行业卡轮询",
CardCategory: ptr("industry"),
Priority: 15,
CarddataCheckInterval: ptr(3600), // 1小时
PackageCheckInterval: ptr(3600),
Status: 1,
Description: "行业卡无需实名检查,每小时检查流量和套餐",
},
{
ConfigName: "已实名卡轮询",
CardCondition: ptr("real_name"),
Priority: 20,
RealnameCheckInterval: ptr(86400), // 1天
Status: 1,
Description: "已实名卡每天检查一次实名状态",
},
{
ConfigName: "已激活卡轮询",
CardCondition: ptr("activated"),
Priority: 30,
CarddataCheckInterval: ptr(3600), // 1小时
PackageCheckInterval: ptr(3600),
Status: 1,
Description: "已激活卡每小时检查流量和套餐",
},
{
ConfigName: "默认轮询配置",
Priority: 100,
RealnameCheckInterval: ptr(86400),
CarddataCheckInterval: ptr(86400),
PackageCheckInterval: ptr(86400),
Status: 1,
Description: "默认配置,每天检查一次",
},
}
for _, cfg := range configs {
if err := db.Create(&cfg).Error; err != nil {
log.Printf("插入配置失败 [%s]: %v", cfg.ConfigName, err)
} else {
fmt.Printf(" + %s (优先级: %d)\n", cfg.ConfigName, cfg.Priority)
}
}
fmt.Println("✓ 轮询配置初始化完成")
// 插入并发控制配置5+ Worker 场景,每种任务 2000-5000 并发)
concurrencyConfigs := []PollingConcurrencyConfig{
{TaskType: "realname", MaxConcurrency: 5000, Description: "实名检查任务最大并发数"},
{TaskType: "carddata", MaxConcurrency: 5000, Description: "流量检查任务最大并发数"},
{TaskType: "package", MaxConcurrency: 5000, Description: "套餐检查任务最大并发数"},
{TaskType: "stop_start", MaxConcurrency: 5000, Description: "停复机操作最大并发数"},
}
for _, cfg := range concurrencyConfigs {
if err := db.Create(&cfg).Error; err != nil {
log.Printf("插入并发配置失败 [%s]: %v", cfg.TaskType, err)
} else {
fmt.Printf(" + %s (最大并发: %d)\n", cfg.TaskType, cfg.MaxConcurrency)
}
}
fmt.Println("✓ 并发控制配置初始化完成")
// 验证
var pollingCount, concurrencyCount int64
db.Model(&PollingConfig{}).Count(&pollingCount)
db.Model(&PollingConcurrencyConfig{}).Count(&concurrencyCount)
fmt.Printf("\n=== 初始化完成 ===\n")
fmt.Printf("轮询配置: %d 条\n", pollingCount)
fmt.Printf("并发配置: %d 条\n", concurrencyCount)
}