1
0
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:
Jebbs
2021-01-30 08:31:11 +08:00
committed by Shelikhoo
parent dde9463275
commit fa0cf6db26
37 changed files with 3655 additions and 264 deletions

View File

@@ -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
}