mirror of
https://github.com/v2fly/v2ray-core.git
synced 2026-01-30 12:55:24 -05:00
v5: Health Check & LeastLoad Strategy (rebased from 2c5a714903)
Some changes will be necessary to integrate it into V2Ray
This commit is contained in:
@@ -5,8 +5,8 @@ package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/v2fly/v2ray-core/v4/features/routing"
|
||||
|
||||
"github.com/v2fly/v2ray-core/v4/common/dice"
|
||||
"github.com/v2fly/v2ray-core/v4/features/extension"
|
||||
"github.com/v2fly/v2ray-core/v4/features/outbound"
|
||||
)
|
||||
@@ -15,34 +15,37 @@ type BalancingStrategy interface {
|
||||
PickOutbound([]string) string
|
||||
}
|
||||
|
||||
type RandomStrategy struct{}
|
||||
|
||||
func (s *RandomStrategy) PickOutbound(tags []string) string {
|
||||
n := len(tags)
|
||||
if n == 0 {
|
||||
panic("0 tags")
|
||||
}
|
||||
|
||||
return tags[dice.Roll(n)]
|
||||
}
|
||||
|
||||
type Balancer struct {
|
||||
selectors []string
|
||||
strategy BalancingStrategy
|
||||
ohm outbound.Manager
|
||||
selectors []string
|
||||
strategy routing.BalancingStrategy
|
||||
ohm outbound.Manager
|
||||
fallbackTag string
|
||||
|
||||
override overridden
|
||||
}
|
||||
|
||||
// PickOutbound picks the tag of a outbound
|
||||
func (b *Balancer) PickOutbound() (string, error) {
|
||||
hs, ok := b.ohm.(outbound.HandlerSelector)
|
||||
if !ok {
|
||||
return "", newError("outbound.Manager is not a HandlerSelector")
|
||||
candidates, err := b.SelectOutbounds()
|
||||
if err != nil {
|
||||
if b.fallbackTag != "" {
|
||||
newError("fallback to [", b.fallbackTag, "], due to error: ", err).AtInfo().WriteToLog()
|
||||
return b.fallbackTag, nil
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
tags := hs.Select(b.selectors)
|
||||
if len(tags) == 0 {
|
||||
return "", newError("no available outbounds selected")
|
||||
var tag string
|
||||
if o := b.override.Get(); o != nil {
|
||||
tag = b.strategy.Pick(o.selects)
|
||||
} else {
|
||||
tag = b.strategy.SelectAndPick(candidates)
|
||||
}
|
||||
tag := b.strategy.PickOutbound(tags)
|
||||
if tag == "" {
|
||||
if b.fallbackTag != "" {
|
||||
newError("fallback to [", b.fallbackTag, "], due to empty tag returned").AtInfo().WriteToLog()
|
||||
return b.fallbackTag, nil
|
||||
}
|
||||
// will use default handler
|
||||
return "", newError("balancing strategy returns empty tag")
|
||||
}
|
||||
return tag, nil
|
||||
@@ -53,3 +56,13 @@ func (b *Balancer) InjectContext(ctx context.Context) {
|
||||
contextReceiver.InjectContext(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// SelectOutbounds select outbounds with selectors of the Balancer
|
||||
func (b *Balancer) SelectOutbounds() ([]string, error) {
|
||||
hs, ok := b.ohm.(outbound.HandlerSelector)
|
||||
if !ok {
|
||||
return nil, newError("outbound.Manager is not a HandlerSelector")
|
||||
}
|
||||
tags := hs.Select(b.selectors)
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user