Compare commits

...

4 Commits

Author SHA1 Message Date
Aubrey Yang
00d58f9972
Merge 256e9d8c3d into 50d60cb004 2024-06-11 21:07:44 +08:00
xishang0128
50d60cb004 chore: Disable the loop back detector for CMFA 2024-06-11 20:52:41 +08:00
Aubrey Yang
256e9d8c3d
Update loadbalance.go 2024-04-17 18:21:59 +09:00
Aubrey Yang
828ba83ef3
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.
2024-04-17 18:20:30 +09:00
2 changed files with 26 additions and 21 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/metacubex/mihomo/component/loopback"
"github.com/metacubex/mihomo/component/resolver"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
)
type Direct struct {
@ -24,8 +25,10 @@ type DirectOption struct {
// DialContext implements C.ProxyAdapter
func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
if err := d.loopBack.CheckConn(metadata); err != nil {
return nil, err
if !features.CMFA {
if err := d.loopBack.CheckConn(metadata); err != nil {
return nil, err
}
}
opts = append(opts, dialer.WithResolver(resolver.DefaultResolver))
c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
@ -38,8 +41,10 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
// ListenPacketContext implements C.ProxyAdapter
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
if err := d.loopBack.CheckPacketConn(metadata); err != nil {
return nil, err
if !features.CMFA {
if err := d.loopBack.CheckPacketConn(metadata); err != nil {
return nil, err
}
}
// net.UDPConn.WriteTo only working with *net.UDPAddr, so we need a net.UDPAddr
if !metadata.Resolved() {

View File

@ -5,8 +5,8 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"sync"
"net"
"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
}
}