我想要制作一个能够循环真实事物的算法,在我的情况下以预定义的比例后端服务器。
例如我有2个后端服务器
type server struct {
addr string
ratio float64
counter int64
}
// s2 is a beast and may handle 3 times the requests then s1 *edit
s1 := &server{":3000", 0.25}
s2 := &server{":3001", 0.75}
func nextServer() {
server := next() // simple goroutine that provides the next server between s1 and s2
N := server.counter / i
if float64(N) > server.ratio {
//repeat this function
return nextServer()
}
server.counter += 1
}
for i := 0; i < 1000; i++ {
nextServer()
}
这是我得到的一个非常简单的实现,但当我像10000时,它一直在循环 nextServer()因为N总是&gt; server.ratio。
只要我大约5000,它就完美无缺。但我认为有更好的算法来循环比率。
如何使这简单而坚实?
答案 0 :(得分:3)
这样的东西?
package main
import (
"fmt"
"math/rand"
)
type server struct {
addr string
ratio float64
}
var servers []server
func nextServer() *server {
rndFloat := rand.Float64() //pick a random number between 0.0-1.0
ratioSum := 0.0
for _, srv := range servers {
ratioSum += srv.ratio //sum ratios of all previous servers in list
if ratioSum >= rndFloat { //if ratiosum rises above the random number
return &srv //return that server
}
}
return nil //should not come here
}
func main() {
servers = []server{server{"0.25", 0.25}, server{"0.50", 0.50},
server{"0.10", 0.10}, server{"0.15", 0.15}}
counts := make(map[string]int, len(servers))
for i := 0; i < 100; i++ {
srv := nextServer()
counts[srv.addr] += 1
}
fmt.Println(counts)
}
收益率例如:
map[0.50:56 0.15:15 0.25:24 0.10:5]