mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-23 16:58:31 +02:00
refactor: fix incorrect logic introduced in previous commits and improve error handling
This commit is contained in:
@@ -3,6 +3,7 @@ package loadbalancer
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/bytedance/gopkg/util/xxhash3"
|
||||
@@ -39,16 +40,6 @@ func (impl *ipHash) OnAddServer(srv types.LoadBalancerServer) {
|
||||
impl.mu.Lock()
|
||||
defer impl.mu.Unlock()
|
||||
|
||||
for i, s := range impl.pool {
|
||||
if s == srv {
|
||||
return
|
||||
}
|
||||
if s == nil {
|
||||
impl.pool[i] = srv
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
impl.pool = append(impl.pool, srv)
|
||||
}
|
||||
|
||||
@@ -58,27 +49,33 @@ func (impl *ipHash) OnRemoveServer(srv types.LoadBalancerServer) {
|
||||
|
||||
for i, s := range impl.pool {
|
||||
if s == srv {
|
||||
impl.pool[i] = nil
|
||||
impl.pool = slices.Delete(impl.pool, i, 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (impl *ipHash) ServeHTTP(_ types.LoadBalancerServers, rw http.ResponseWriter, r *http.Request) {
|
||||
if impl.realIP != nil {
|
||||
// resolve real client IP
|
||||
if proceed := impl.realIP.TryModifyRequest(rw, r); !proceed {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
srv := impl.ChooseServer(impl.pool, r)
|
||||
if srv == nil || srv.Status().Bad() {
|
||||
http.Error(rw, "Service unavailable", http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
|
||||
if impl.realIP != nil {
|
||||
impl.realIP.ModifyRequest(srv.ServeHTTP, rw, r)
|
||||
} else {
|
||||
srv.ServeHTTP(rw, r)
|
||||
}
|
||||
srv.ServeHTTP(rw, r)
|
||||
}
|
||||
|
||||
func (impl *ipHash) ChooseServer(_ types.LoadBalancerServers, r *http.Request) types.LoadBalancerServer {
|
||||
impl.mu.Lock()
|
||||
defer impl.mu.Unlock()
|
||||
|
||||
if len(impl.pool) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ func (impl *leastConn) ServeHTTP(srvs types.LoadBalancerServers, rw http.Respons
|
||||
}
|
||||
|
||||
minConn.Add(1)
|
||||
defer minConn.Add(-1)
|
||||
srv.ServeHTTP(rw, r)
|
||||
minConn.Add(-1)
|
||||
}
|
||||
|
||||
func (impl *leastConn) ChooseServer(srvs types.LoadBalancerServers, r *http.Request) types.LoadBalancerServer {
|
||||
@@ -55,18 +55,15 @@ func (impl *leastConn) ChooseServer(srvs types.LoadBalancerServers, r *http.Requ
|
||||
return nil
|
||||
}
|
||||
|
||||
srv := srvs[0]
|
||||
minConn, ok := impl.nConn.Load(srv)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
var srv types.LoadBalancerServer
|
||||
var minConn *atomic.Int64
|
||||
|
||||
for i := 1; i < len(srvs); i++ {
|
||||
for i := range srvs {
|
||||
nConn, ok := impl.nConn.Load(srvs[i])
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if nConn.Load() < minConn.Load() {
|
||||
if minConn == nil || nConn.Load() < minConn.Load() {
|
||||
minConn = nConn
|
||||
srv = srvs[i]
|
||||
}
|
||||
|
||||
@@ -364,11 +364,5 @@ func isIdlewatcherRequest(r *http.Request) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if this is a page refresh after idlewatcher wake up
|
||||
// by looking for the sticky session cookie
|
||||
if _, err := r.Cookie("godoxy_lb_sticky"); err == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -21,9 +21,6 @@ func (lb *roundRobin) ChooseServer(srvs types.LoadBalancerServers, r *http.Reque
|
||||
if len(srvs) == 0 {
|
||||
return nil
|
||||
}
|
||||
index := lb.index.Add(1) % uint32(len(srvs))
|
||||
if lb.index.Load() >= 2*uint32(len(srvs)) {
|
||||
lb.index.Store(0)
|
||||
}
|
||||
index := (lb.index.Add(1) - 1) % uint32(len(srvs))
|
||||
return srvs[index]
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package loadbalancer
|
||||
import (
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
@@ -46,5 +47,5 @@ func setStickyCookie(rw http.ResponseWriter, r *http.Request, srv types.LoadBala
|
||||
}
|
||||
|
||||
func isSecure(r *http.Request) bool {
|
||||
return r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https"
|
||||
return r.TLS != nil || strings.EqualFold(r.Header.Get("X-Forwarded-Proto"), "https")
|
||||
}
|
||||
|
||||
@@ -170,6 +170,13 @@ func (m *Middleware) ModifyRequest(next http.HandlerFunc, w http.ResponseWriter,
|
||||
next(w, r)
|
||||
}
|
||||
|
||||
func (m *Middleware) TryModifyRequest(w http.ResponseWriter, r *http.Request) (proceed bool) {
|
||||
if exec, ok := m.impl.(RequestModifier); ok {
|
||||
return exec.before(w, r)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *Middleware) ModifyResponse(resp *http.Response) error {
|
||||
if exec, ok := m.impl.(ResponseModifier); ok {
|
||||
return exec.modifyResponse(resp)
|
||||
|
||||
Reference in New Issue
Block a user