[feat] load balancing across different clusters and endpoints based on metrics (#3063)

This commit is contained in:
rinfx
2025-11-25 10:32:34 +08:00
committed by GitHub
parent 7a504fd67d
commit 42334f21df
12 changed files with 764 additions and 126 deletions

View File

@@ -7,9 +7,10 @@ import (
"github.com/higress-group/wasm-go/pkg/wrapper"
"github.com/tidwall/gjson"
global_least_request "github.com/alibaba/higress/plugins/wasm-go/extensions/ai-load-balancer/global_least_request"
least_busy "github.com/alibaba/higress/plugins/wasm-go/extensions/ai-load-balancer/least_busy"
prefix_cache "github.com/alibaba/higress/plugins/wasm-go/extensions/ai-load-balancer/prefix_cache"
"github.com/alibaba/higress/plugins/wasm-go/extensions/ai-load-balancer/cluster_metrics"
"github.com/alibaba/higress/plugins/wasm-go/extensions/ai-load-balancer/endpoint_metrics"
"github.com/alibaba/higress/plugins/wasm-go/extensions/ai-load-balancer/global_least_request"
"github.com/alibaba/higress/plugins/wasm-go/extensions/ai-load-balancer/prefix_cache"
)
func main() {}
@@ -37,34 +38,57 @@ type LoadBalancer interface {
}
type Config struct {
policy string
lb LoadBalancer
lbType string
lbPolicy string
lb LoadBalancer
}
const (
LeastBusyLoadBalancerPolicy = "least_busy"
GlobalLeastRequestLoadBalancerPolicy = "global_least_request"
PrefixCache = "prefix_cache"
ClusterLoadBalancerType = "cluster"
EndpointLoadBalancerType = "endpoint"
// Cluster load balancer policies
MetricsBasedCluster = "cluster_metrics"
// Endpoint load balancer policies
MetricsBasedEndpoint = "endpoint_metrics"
MetricsBasedEndpointDeprecated = "metrics_based" // Compatible with old configurations, equal to `endpoint_metrics`
GlobalLeastRequestEndpoint = "global_least_request"
PrefixCacheEndpoint = "prefix_cache"
)
func parseConfig(json gjson.Result, config *Config) error {
config.policy = json.Get("lb_policy").String()
config.lbType = json.Get("lb_type").String()
// Compatible with old configurations
if config.lbType == "" {
config.lbType = EndpointLoadBalancerType
}
config.lbPolicy = json.Get("lb_policy").String()
var err error
switch config.policy {
case LeastBusyLoadBalancerPolicy:
config.lb, err = least_busy.NewLeastBusyLoadBalancer(json.Get("lb_config"))
case GlobalLeastRequestLoadBalancerPolicy:
config.lb, err = global_least_request.NewGlobalLeastRequestLoadBalancer(json.Get("lb_config"))
case PrefixCache:
config.lb, err = prefix_cache.NewPrefixCacheLoadBalancer(json.Get("lb_config"))
switch config.lbType {
case ClusterLoadBalancerType:
switch config.lbPolicy {
case MetricsBasedCluster:
config.lb, err = cluster_metrics.NewClusterEndpointLoadBalancer(json.Get("lb_config"))
default:
err = fmt.Errorf("lb_policy %s is not supported", config.lbPolicy)
}
case EndpointLoadBalancerType:
switch config.lbPolicy {
case MetricsBasedEndpoint, MetricsBasedEndpointDeprecated:
config.lb, err = endpoint_metrics.NewMetricsEndpointLoadBalancer(json.Get("lb_config"))
case GlobalLeastRequestEndpoint:
config.lb, err = global_least_request.NewGlobalLeastRequestLoadBalancer(json.Get("lb_config"))
case PrefixCacheEndpoint:
config.lb, err = prefix_cache.NewPrefixCacheLoadBalancer(json.Get("lb_config"))
default:
err = fmt.Errorf("lb_psolicy %s is not supported", config.lbPolicy)
}
default:
err = fmt.Errorf("lb_policy %s is not supported", config.policy)
err = fmt.Errorf("lb_type %s is not supported", config.lbType)
}
return err
}
func onHttpRequestHeaders(ctx wrapper.HttpContext, config Config) types.Action {
ctx.DisableReroute()
return config.lb.HandleHttpRequestHeaders(ctx)
}