mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-22 08:18:29 +02:00
improved health check
This commit is contained in:
@@ -45,10 +45,10 @@ func (impl ipHash) serveHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
idx := hashIP(ip) % uint32(len(impl.pool))
|
||||
if !impl.pool[idx].IsHealthy() {
|
||||
if impl.pool[idx].Status().Bad() {
|
||||
http.Error(rw, "Service unavailable", http.StatusServiceUnavailable)
|
||||
}
|
||||
impl.pool[idx].handler.ServeHTTP(rw, r)
|
||||
impl.pool[idx].ServeHTTP(rw, r)
|
||||
}
|
||||
|
||||
func hashIP(ip string) uint32 {
|
||||
|
||||
@@ -48,6 +48,6 @@ func (impl *leastConn) ServeHTTP(srvs servers, rw http.ResponseWriter, r *http.R
|
||||
}
|
||||
|
||||
minConn.Add(1)
|
||||
srv.handler.ServeHTTP(rw, r)
|
||||
srv.ServeHTTP(rw, r)
|
||||
minConn.Add(-1)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package loadbalancer
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-acme/lego/v4/log"
|
||||
E "github.com/yusing/go-proxy/internal/error"
|
||||
@@ -25,12 +26,13 @@ type (
|
||||
}
|
||||
LoadBalancer struct {
|
||||
impl
|
||||
Config
|
||||
*Config
|
||||
|
||||
pool servers
|
||||
poolMu sync.Mutex
|
||||
|
||||
sumWeight weightType
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
weightType uint16
|
||||
@@ -38,7 +40,7 @@ type (
|
||||
|
||||
const maxWeight weightType = 100
|
||||
|
||||
func New(cfg Config) *LoadBalancer {
|
||||
func New(cfg *Config) *LoadBalancer {
|
||||
lb := &LoadBalancer{Config: cfg, pool: servers{}}
|
||||
mode := cfg.Mode
|
||||
if !cfg.Mode.ValidateUpdate() {
|
||||
@@ -167,6 +169,8 @@ func (lb *LoadBalancer) Start() {
|
||||
if lb.sumWeight != 0 {
|
||||
log.Warnf("weighted mode not supported yet")
|
||||
}
|
||||
|
||||
lb.startTime = time.Now()
|
||||
logger.Debugf("loadbalancer %s started", lb.Link)
|
||||
}
|
||||
|
||||
@@ -178,15 +182,20 @@ func (lb *LoadBalancer) Stop() {
|
||||
logger.Debugf("loadbalancer %s stopped", lb.Link)
|
||||
}
|
||||
|
||||
func (lb *LoadBalancer) Uptime() time.Duration {
|
||||
return time.Since(lb.startTime)
|
||||
}
|
||||
|
||||
func (lb *LoadBalancer) availServers() servers {
|
||||
lb.poolMu.Lock()
|
||||
defer lb.poolMu.Unlock()
|
||||
|
||||
avail := make(servers, 0, len(lb.pool))
|
||||
for _, s := range lb.pool {
|
||||
if s.IsHealthy() {
|
||||
avail = append(avail, s)
|
||||
if s.Status().Bad() {
|
||||
continue
|
||||
}
|
||||
avail = append(avail, s)
|
||||
}
|
||||
return avail
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func TestRebalance(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("zero", func(t *testing.T) {
|
||||
lb := New(Config{})
|
||||
lb := New(new(Config))
|
||||
for range 10 {
|
||||
lb.AddServer(&Server{})
|
||||
}
|
||||
@@ -17,7 +17,7 @@ func TestRebalance(t *testing.T) {
|
||||
ExpectEqual(t, lb.sumWeight, maxWeight)
|
||||
})
|
||||
t.Run("less", func(t *testing.T) {
|
||||
lb := New(Config{})
|
||||
lb := New(new(Config))
|
||||
lb.AddServer(&Server{Weight: weightType(float64(maxWeight) * .1)})
|
||||
lb.AddServer(&Server{Weight: weightType(float64(maxWeight) * .2)})
|
||||
lb.AddServer(&Server{Weight: weightType(float64(maxWeight) * .3)})
|
||||
@@ -28,7 +28,7 @@ func TestRebalance(t *testing.T) {
|
||||
ExpectEqual(t, lb.sumWeight, maxWeight)
|
||||
})
|
||||
t.Run("more", func(t *testing.T) {
|
||||
lb := New(Config{})
|
||||
lb := New(new(Config))
|
||||
lb.AddServer(&Server{Weight: weightType(float64(maxWeight) * .1)})
|
||||
lb.AddServer(&Server{Weight: weightType(float64(maxWeight) * .2)})
|
||||
lb.AddServer(&Server{Weight: weightType(float64(maxWeight) * .3)})
|
||||
|
||||
@@ -15,7 +15,7 @@ func (lb *roundRobin) OnRemoveServer(srv *Server) {}
|
||||
|
||||
func (lb *roundRobin) ServeHTTP(srvs servers, rw http.ResponseWriter, r *http.Request) {
|
||||
index := lb.index.Add(1)
|
||||
srvs[index%uint32(len(srvs))].handler.ServeHTTP(rw, r)
|
||||
srvs[index%uint32(len(srvs))].ServeHTTP(rw, r)
|
||||
if lb.index.Load() >= 2*uint32(len(srvs)) {
|
||||
lb.index.Store(0)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package loadbalancer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/net/types"
|
||||
U "github.com/yusing/go-proxy/internal/utils"
|
||||
@@ -33,10 +34,18 @@ func NewServer(name string, url types.URL, weight weightType, handler http.Handl
|
||||
return srv
|
||||
}
|
||||
|
||||
func (srv *Server) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
srv.handler.ServeHTTP(rw, r)
|
||||
}
|
||||
|
||||
func (srv *Server) String() string {
|
||||
return srv.Name
|
||||
}
|
||||
|
||||
func (srv *Server) IsHealthy() bool {
|
||||
return srv.healthMon.IsHealthy()
|
||||
func (srv *Server) Status() health.Status {
|
||||
return srv.healthMon.Status()
|
||||
}
|
||||
|
||||
func (srv *Server) Uptime() time.Duration {
|
||||
return srv.healthMon.Uptime()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user