Add load balancer with round-robin, failover, and weighted strategies
Implements balancer middleware with URL rewriting per-request: - RoundRobin, Failover, and WeightedRandom endpoint selection strategies - Background HealthChecker with configurable probe interval and path - Thread-safe health state tracking with sync.RWMutex
This commit is contained in:
42
balancer/weighted.go
Normal file
42
balancer/weighted.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package balancer
|
||||
|
||||
import "math/rand/v2"
|
||||
|
||||
type weightedRandom struct{}
|
||||
|
||||
// WeightedRandom returns a strategy that selects endpoints randomly,
|
||||
// weighted by each endpoint's Weight field. Endpoints with Weight <= 0
|
||||
// are treated as having a weight of 1.
|
||||
func WeightedRandom() Strategy {
|
||||
return &weightedRandom{}
|
||||
}
|
||||
|
||||
func (w *weightedRandom) Next(healthy []Endpoint) (Endpoint, error) {
|
||||
if len(healthy) == 0 {
|
||||
return Endpoint{}, ErrNoHealthy
|
||||
}
|
||||
|
||||
totalWeight := 0
|
||||
for _, ep := range healthy {
|
||||
weight := ep.Weight
|
||||
if weight <= 0 {
|
||||
weight = 1
|
||||
}
|
||||
totalWeight += weight
|
||||
}
|
||||
|
||||
r := rand.IntN(totalWeight)
|
||||
for _, ep := range healthy {
|
||||
weight := ep.Weight
|
||||
if weight <= 0 {
|
||||
weight = 1
|
||||
}
|
||||
r -= weight
|
||||
if r < 0 {
|
||||
return ep, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Should never reach here, but return last endpoint as a safeguard.
|
||||
return healthy[len(healthy)-1], nil
|
||||
}
|
||||
Reference in New Issue
Block a user