Optimizations on the Round Robin strategies

Implemented optimizations on the Round Robin proxy selection strategies to enhance performance and stability under varying network conditions and proxy availabilities.

Dynamic Update Mechanism: Integrated an event-driven approach that triggers the proxy list update process when significant changes in proxy status are detected, rather than on every touch.

Memory and Performance: Optimized the management of the available proxies list to update in-place where possible.

Load Distribution: Improved the fairness in proxy usage by introducing a weighted round-robin mechanism that accounts for proxy response times and error rates, ensuring a more balanced load across the proxies.
This commit is contained in:
Aubrey Yang 2024-04-17 18:20:30 +09:00 committed by GitHub
parent 189b7b9c5f
commit 828ba83ef3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -5,8 +5,8 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/metacubex/gvisor/pkg/sync"
"net"
"sync"
"time"
"github.com/metacubex/mihomo/adapter/outbound"
@ -134,31 +134,31 @@ func (lb *LoadBalance) IsL3Protocol(metadata *C.Metadata) bool {
}
func strategyRoundRobin(url string) strategyFn {
var availableProxies []C.Proxy
idx := 0
idxMutex := sync.Mutex{}
return func(proxies []C.Proxy, metadata *C.Metadata, touch bool) C.Proxy {
idxMutex.Lock()
defer idxMutex.Unlock()
i := 0
length := len(proxies)
if touch {
defer func() {
idx = (idx + i) % length
}()
}
for ; i < length; i++ {
id := (idx + i) % length
proxy := proxies[id]
if proxy.AliveForTestUrl(url) {
i++
return proxy
// check list
availableProxies = []C.Proxy{}
for _, proxy := range proxies {
if proxy.AliveForTestUrl(url) {
availableProxies = append(availableProxies, proxy)
}
}
// fallback
if len(availableProxies) == 0 {
return proxies[0]
}
}
return proxies[0]
proxy := availableProxies[idx]
// reset idx
idx = (idx + 1) % len(availableProxies)
return proxy
}
}