Vastly improve the way load balancing works
This commit is contained in:
parent
2e8699d483
commit
14075e31dc
|
@ -83,6 +83,20 @@ func Max(a, b int) int {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MinF(a, b float64) float64 {
|
||||||
|
if a < b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func MaxF(a, b float64) float64 {
|
||||||
|
if a > b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
func StringReverse(s string) string {
|
func StringReverse(s string) string {
|
||||||
r := []rune(s)
|
r := []rune(s)
|
||||||
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
|
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
|
||||||
|
|
|
@ -167,8 +167,28 @@ func (serversInfo *ServersInfo) getOne() *ServerInfo {
|
||||||
if candidate == 0 {
|
if candidate == 0 {
|
||||||
return &serversInfo.inner[candidate]
|
return &serversInfo.inner[candidate]
|
||||||
}
|
}
|
||||||
if serversInfo.inner[candidate].rtt.Value() < serversInfo.inner[0].rtt.Value() {
|
candidateRtt, currentBestRtt := serversInfo.inner[candidate].rtt.Value(), serversInfo.inner[0].rtt.Value()
|
||||||
|
if currentBestRtt < 0 {
|
||||||
|
currentBestRtt = candidateRtt
|
||||||
|
serversInfo.inner[0].rtt.Set(currentBestRtt)
|
||||||
|
}
|
||||||
|
partialSort := false
|
||||||
|
if candidateRtt < currentBestRtt {
|
||||||
serversInfo.inner[candidate], serversInfo.inner[0] = serversInfo.inner[0], serversInfo.inner[candidate]
|
serversInfo.inner[candidate], serversInfo.inner[0] = serversInfo.inner[0], serversInfo.inner[candidate]
|
||||||
|
partialSort = true
|
||||||
|
dlog.Debugf("New prefered candidate: %v (rtt: %v vs previous: %v)", serversInfo.inner[0].Name, candidateRtt, currentBestRtt)
|
||||||
|
} else if candidateRtt >= currentBestRtt*4.0 {
|
||||||
|
if time.Since(serversInfo.inner[candidate].lastActionTS) > time.Duration(1*time.Minute) {
|
||||||
|
serversInfo.inner[candidate].rtt.Add(MinF(MaxF(candidateRtt/2.0, currentBestRtt*2.0), candidateRtt))
|
||||||
|
partialSort = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if partialSort {
|
||||||
|
for i := 1; i < serversCount; i++ {
|
||||||
|
if serversInfo.inner[i-1].rtt.Value() > serversInfo.inner[i].rtt.Value() {
|
||||||
|
serversInfo.inner[i-1], serversInfo.inner[i] = serversInfo.inner[i], serversInfo.inner[i-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch serversInfo.lbStrategy {
|
switch serversInfo.lbStrategy {
|
||||||
case LBStrategyFastest:
|
case LBStrategyFastest:
|
||||||
|
@ -315,7 +335,7 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st
|
||||||
|
|
||||||
func (serverInfo *ServerInfo) noticeFailure(proxy *Proxy) {
|
func (serverInfo *ServerInfo) noticeFailure(proxy *Proxy) {
|
||||||
serverInfo.Lock()
|
serverInfo.Lock()
|
||||||
serverInfo.rtt.Set(float64(proxy.timeout.Nanoseconds()))
|
serverInfo.rtt.Add(float64(proxy.timeout.Nanoseconds() / 1000000))
|
||||||
serverInfo.Unlock()
|
serverInfo.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,9 +348,10 @@ func (serverInfo *ServerInfo) noticeBegin(proxy *Proxy) {
|
||||||
func (serverInfo *ServerInfo) noticeSuccess(proxy *Proxy) {
|
func (serverInfo *ServerInfo) noticeSuccess(proxy *Proxy) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
serverInfo.Lock()
|
serverInfo.Lock()
|
||||||
elapsed := now.Sub(serverInfo.lastActionTS) / 1024
|
elapsed := now.Sub(serverInfo.lastActionTS)
|
||||||
if elapsed > 0 {
|
elapsedMs := elapsed.Nanoseconds() / 1000000
|
||||||
serverInfo.rtt.Add(float64(elapsed))
|
if elapsedMs > 0 && elapsed < proxy.timeout {
|
||||||
|
serverInfo.rtt.Add(float64(elapsedMs))
|
||||||
}
|
}
|
||||||
serverInfo.Unlock()
|
serverInfo.Unlock()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue