Print the sorted list of latencies

Add an option to disable the load-balancing estimator
This commit is contained in:
Frank Denis 2019-06-03 13:04:34 +02:00
parent a417f0d282
commit 9e2a945fff
4 changed files with 34 additions and 12 deletions

View File

@ -40,6 +40,7 @@ type Config struct {
CertIgnoreTimestamp bool `toml:"cert_ignore_timestamp"` CertIgnoreTimestamp bool `toml:"cert_ignore_timestamp"`
EphemeralKeys bool `toml:"dnscrypt_ephemeral_keys"` EphemeralKeys bool `toml:"dnscrypt_ephemeral_keys"`
LBStrategy string `toml:"lb_strategy"` LBStrategy string `toml:"lb_strategy"`
LBEstimator bool `toml:"lb_estimator"`
BlockIPv6 bool `toml:"block_ipv6"` BlockIPv6 bool `toml:"block_ipv6"`
Cache bool Cache bool
CacheSize int `toml:"cache_size"` CacheSize int `toml:"cache_size"`
@ -317,6 +318,7 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error {
dlog.Warnf("Unknown load balancing strategy: [%s]", config.LBStrategy) dlog.Warnf("Unknown load balancing strategy: [%s]", config.LBStrategy)
} }
proxy.serversInfo.lbStrategy = lbStrategy proxy.serversInfo.lbStrategy = lbStrategy
proxy.serversInfo.lbEstimator = config.LBEstimator
proxy.listenAddresses = config.ListenAddresses proxy.listenAddresses = config.ListenAddresses
proxy.daemonize = config.Daemonize proxy.daemonize = config.Daemonize

View File

@ -122,6 +122,11 @@ refused_code_in_responses = false
# lb_strategy = 'p2' # lb_strategy = 'p2'
## Set to `true` to constantly try to estimate the latency of all the resolvers
## and adjust the load-balancing parameters accordingly, or to `false` to disable.
# lb_estimator = true
## Log level (0-6, default: 2 - 0 is very verbose, 6 only contains fatal errors) ## Log level (0-6, default: 2 - 0 is very verbose, 6 only contains fatal errors)

View File

@ -461,6 +461,6 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
func NewProxy() Proxy { func NewProxy() Proxy {
return Proxy{ return Proxy{
serversInfo: ServersInfo{lbStrategy: DefaultLBStrategy}, serversInfo: ServersInfo{lbStrategy: DefaultLBStrategy, lbEstimator: true},
} }
} }

View File

@ -67,6 +67,7 @@ type ServersInfo struct {
inner []*ServerInfo inner []*ServerInfo
registeredServers []RegisteredServer registeredServers []RegisteredServer
lbStrategy LBStrategy lbStrategy LBStrategy
lbEstimator bool
} }
func (serversInfo *ServersInfo) registerServer(proxy *Proxy, name string, stamp stamps.ServerStamp) error { func (serversInfo *ServersInfo) registerServer(proxy *Proxy, name string, stamp stamps.ServerStamp) error {
@ -142,6 +143,12 @@ func (serversInfo *ServersInfo) refresh(proxy *Proxy) (int, error) {
} }
} }
serversInfo.inner = inner serversInfo.inner = inner
dlog.Notice("Sorted latencies:")
for i := 0; i < innerLen; i++ {
dlog.Noticef("- %5dms %s", inner[i].initialRtt, inner[i].Name)
}
if innerLen > 0 { if innerLen > 0 {
dlog.Noticef("Server with the lowest initial latency: %s (rtt: %dms)", inner[0].Name, inner[0].initialRtt) dlog.Noticef("Server with the lowest initial latency: %s (rtt: %dms)", inner[0].Name, inner[0].initialRtt)
proxy.certIgnoreTimestamp = false proxy.certIgnoreTimestamp = false
@ -157,17 +164,7 @@ func (serversInfo *ServersInfo) liveServers() int {
return liveServers return liveServers
} }
func (serversInfo *ServersInfo) getOne() *ServerInfo { func (serversInfo *ServersInfo) estimatorUpdate(candidate int) {
serversInfo.Lock()
defer serversInfo.Unlock()
serversCount := len(serversInfo.inner)
if serversCount <= 0 {
return nil
}
candidate := rand.Intn(serversCount)
if candidate == 0 {
return serversInfo.inner[candidate]
}
candidateRtt, currentBestRtt := 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 { if currentBestRtt < 0 {
currentBestRtt = candidateRtt currentBestRtt = candidateRtt
@ -185,12 +182,30 @@ func (serversInfo *ServersInfo) getOne() *ServerInfo {
} }
} }
if partialSort { if partialSort {
serversCount := len(serversInfo.inner)
for i := 1; i < serversCount; i++ { for i := 1; i < serversCount; i++ {
if serversInfo.inner[i-1].rtt.Value() > serversInfo.inner[i].rtt.Value() { 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] serversInfo.inner[i-1], serversInfo.inner[i] = serversInfo.inner[i], serversInfo.inner[i-1]
} }
} }
} }
}
func (serversInfo *ServersInfo) getOne() *ServerInfo {
serversInfo.Lock()
defer serversInfo.Unlock()
serversCount := len(serversInfo.inner)
if serversCount <= 0 {
return nil
}
if serversInfo.lbEstimator {
candidate := rand.Intn(serversCount)
if candidate == 0 {
return serversInfo.inner[candidate]
}
serversInfo.estimatorUpdate(candidate)
}
var candidate int
switch serversInfo.lbStrategy { switch serversInfo.lbStrategy {
case LBStrategyFirst: case LBStrategyFirst:
candidate = 0 candidate = 0