go随聊-负载均衡[轮询]

         在分布式系统中,负载均衡是非常重要的环节,通过负载均衡将请求派发到网络中的一个或多个节点上进行处理。通常来说,负载均衡分为硬件负载均衡及软件负载均衡。硬件负载均衡,顾名思义,在服务器节点之间安装专门的硬件进行负载均衡的工作,F5便为其中的佼佼者。软件负载均衡则是通过在服务器上安装的特定的负载均衡软件或是自带负载均衡模块完成对请求的分配派发。

go随聊-负载均衡[轮询]_第1张图片

轮询算法

  • 轮循,按公约后的权重设置轮循比率。
  • 存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

GO实现

接口定义:

type LoadBalance interface {
    //选择一个后端Server
    //参数remove是需要排除选择的后端Server
    Select(remove []string) *tool.Server
    //更新可用Server列表
    UpdateServers(servers []*tool.Server)
}

后端Server定义:

type Server struct {
    //主机地址
    Host string
    //主机名		
    Name string		
    Weight int	
    //主机是否在线	
    Online bool		
}

算法实现:

type LoadBalanceRoundRobin struct{
	curSeq helper.AtomicUint64
	servers []*tool.Server
}

func NewLoadBalanceRoundRobin(servers []*tool.Server) *LoadBalanceRoundRobin{
	new:=&LoadBalanceRoundRobin{}
	new.UpdateServers(servers)
	return new
}

func (this *LoadBalanceRoundRobin) UpdateServers(servers []*tool.Server) {
	newServers:=make([]*tool.Server,0)
	for _,e:=range servers {
		if e.Online==true {
			newServers=append(newServers,e)
		}
	}
	this.servers=newServers
}

func (this *LoadBalanceRoundRobin) Select(remove []string) *tool.Server {
	curServer:=this.servers
	if len(curServer)==0 {
		return nil
	}

	if len(remove) == 0 {
		id:=this.curSeq.IncrementAndGet()%uint64(len(curServer))
		return curServer[id]
	}else{
		tmp:=make([]*tool.Server,0)
		for _,s:=range curServer {
			isFind:=false
			for _,v:=range remove {
				if s.Host==v {
					isFind=true
					break
				}
			}
			if isFind==false {
				tmp=append(tmp,s)
			}
		}
		if len(tmp)==0 {
			return nil
		}
		id:=this.curSeq.IncrementAndGet()%uint64(len(tmp))
		return tmp[id]
	}
}

func (this *LoadBalanceRoundRobin) String() string {
	return "RoundRobin"
}

测试:

//创建4个Server,轮询100000次
func TestNewLoadBalanceRoundRobin(t *testing.T) {
	count:=make([]int,4)
	servers:=make([]*tool.Server,0)
	servers=append(servers,&tool.Server{Host:"1",Weight:0,Online:true})
	servers=append(servers,&tool.Server{Host:"2",Weight:1,Online:true})
	servers=append(servers,&tool.Server{Host:"3",Weight:2,Online:true})
	servers=append(servers,&tool.Server{Host:"4",Weight:3,Online:true})
	lb:=NewLoadBalanceRoundRobin(servers)

	for i:=0;i<100000;i++{
		c:=lb.Select(nil)
		count[c.Weight]++
	}
	fmt.Println(count)
}
--------------------------------------------------------
[25000 25000 25000 25000]

go随聊-负载均衡[轮询]_第2张图片

 

你可能感兴趣的:(go随聊,go入了门就不想放弃)