package optimizer import ( "log" "time" "goproxy/config" "goproxy/fetcher" "goproxy/pool" "goproxy/storage" "goproxy/validator" ) // Optimizer 优化轮换器 type Optimizer struct { storage *storage.Storage fetcher *fetcher.Fetcher validator *validator.Validator poolMgr *pool.Manager cfg *config.Config } func NewOptimizer(s *storage.Storage, f *fetcher.Fetcher, v *validator.Validator, pm *pool.Manager, cfg *config.Config) *Optimizer { return &Optimizer{ storage: s, fetcher: f, validator: v, poolMgr: pm, cfg: cfg, } } // RunOnce 执行一次优化轮换 func (o *Optimizer) RunOnce() { start := time.Now() log.Println("[optimize] 🎯 开始优化轮换...") // 获取池子状态 status, err := o.poolMgr.GetStatus() if err != nil { log.Printf("[optimize] 获取状态失败: %v", err) return } // 只有健康状态才执行优化 if status.State != "healthy" { log.Printf("[optimize] 池子状态 %s,跳过优化", status.State) return } // 抓取新的候选代理(优化模式) log.Println("[optimize] 抓取新候选代理...") candidates, err := o.fetcher.FetchSmart("optimize", "") if err != nil { log.Printf("[optimize] 抓取失败: %v", err) return } log.Printf("[optimize] 抓取到 %d 个候选代理", len(candidates)) // 验证候选代理 validCandidates := []storage.Proxy{} for result := range o.validator.ValidateStream(candidates) { if result.Valid { latencyMs := int(result.Latency.Milliseconds()) // 只保留延迟在健康标准内的 if latencyMs <= o.cfg.MaxLatencyHealthy { validCandidates = append(validCandidates, storage.Proxy{ Address: result.Proxy.Address, Protocol: result.Proxy.Protocol, ExitIP: result.ExitIP, ExitLocation: result.ExitLocation, Latency: latencyMs, }) } } } log.Printf("[optimize] 验证通过 %d 个优质候选(延迟<%dms)", len(validCandidates), o.cfg.MaxLatencyHealthy) if len(validCandidates) == 0 { log.Println("[optimize] 无优质候选,跳过优化") return } // 尝试用优质候选替换延迟高的代理 replacedCount := 0 for _, candidate := range validCandidates { added, reason := o.poolMgr.TryAddProxy(candidate) if added && reason == "replaced" { replacedCount++ } } elapsed := time.Since(start) log.Printf("[optimize] ✅ 完成: 替换 %d 个代理 耗时%v", replacedCount, elapsed) } // StartBackground 后台定时优化 func (o *Optimizer) StartBackground() { ticker := time.NewTicker(time.Duration(o.cfg.OptimizeInterval) * time.Minute) go func() { for range ticker.C { o.RunOnce() } }() log.Printf("[optimize] 优化轮换器已启动,间隔 %d 分钟", o.cfg.OptimizeInterval) }