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
43 lines
862 B
Go
43 lines
862 B
Go
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
|
|
}
|