循环遍历服务器的Go算法,按预定义的比例进行分配。

huangapple go评论96阅读模式
英文:

Go algorithm for looping through servers in predefined ratio

问题

我正在尝试创建一个算法,可以按照预定义的比例在后端服务器中循环执行操作。

例如,我有两个后端服务器:

type server struct {
    addr    string
    ratio   float64
    counter int64
}

// s2 是一个强大的服务器,可以处理比 s1 多 3 倍的请求 *编辑
s1 := &server{":3000", 0.25}
s2 := &server{":3001", 0.75}

func nextServer() {
    server := next() // 简单的 goroutine,用于在 s1 和 s2 之间选择下一个服务器
    N := server.counter / i
    if float64(N) > server.ratio {
        // 重复调用这个函数
        return nextServer()
    }
    
    server.counter += 1
}    

for i := 0; i < 1000; i++ {
    nextServer()
}
  • s1 的计数器(处理的请求)为 250
  • s2 是一个庞大的服务器,计数器为 750

这只是我所拥有的内容的一个非常简单的实现,但当 i 大约为 10000 时,它在 nextServer() 中不断循环,因为 N 总是大于 server.ratio。

只要 i 大约为 5000,它就能完美运行。但我认为有更好的算法可以按照比例进行循环。

如何使这个算法简单而稳定?

英文:

I am tying to make a algorithm that can loop true things, backend server in my case by a pre defined ratio.

for example I got 2 backend servers

type server struct {
    addr string
    ratio float64
    counter int64
}

// s2 is a beast and may handle 3 times the requests then s1 *edit
s1 := &amp;server{&quot;:3000&quot;, 0.25}
s2 := &amp;server{&quot;:3001&quot;, 0.75}

func nextServer() {
    server := next() // simple goroutine that provides the next server between s1 and s2
    N := server.counter / i
    if float64(N) &gt; server.ratio {
        //repeat this function
        return nextServer()
    }
    
    server.counter += 1
}    

for i := 0; i &lt; 1000; i++ {
    nextServer()
}
  • s1 has 250 as counter (requests handled)
  • s2 is huge so he has 750 as counter (requests handled)

this is a very simple implementation of what I got but when i is like 10000, it keeps looping in
nextServer() cause N is always > server.ratio.

as long as i is around 5000 it works perfect. but I think there are better algorithms for looping in ratios.

How to make this simple and solid?

答案1

得分: 3

像这样吗?

package main

import (
	"fmt"
	"math/rand"
)

type server struct {
	addr  string
	ratio float64
}

var servers []server

func nextServer() *server {
	rndFloat := rand.Float64() // 在0.0-1.0之间选择一个随机数
	ratioSum := 0.0
	for _, srv := range servers {
		ratioSum += srv.ratio // 将列表中所有先前服务器的比率相加
		if ratioSum >= rndFloat { // 如果比率总和超过随机数
			return &srv // 返回该服务器
		}
	}
	return nil // 不应该到达这里
}

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]
英文:

Something like this?

package main

import (
	&quot;fmt&quot;
	&quot;math/rand&quot;
)

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 &gt;= rndFloat { //if ratiosum rises above the random number
			return &amp;srv //return that server
		}
	}
	return nil //should not come here
}

func main() {
	servers = []server{server{&quot;0.25&quot;, 0.25}, server{&quot;0.50&quot;, 0.50}, 
            server{&quot;0.10&quot;, 0.10}, server{&quot;0.15&quot;, 0.15}}

	counts := make(map[string]int, len(servers))
	for i := 0; i &lt; 100; i++ {
		srv := nextServer()
		counts[srv.addr] += 1
	}
	fmt.Println(counts)
}

Yields for example:

map[0.50:56 0.15:15 0.25:24 0.10:5]

huangapple
  • 本文由 发表于 2014年9月24日 19:32:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/26015847.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定