在分布式系统中,负载均衡是非常重要的环节,通过负载均衡将请求派发到网络中的一个或多个节点上进行处理。通常来说,负载均衡分为硬件负载均衡及软件负载均衡。硬件负载均衡,顾名思义,在服务器节点之间安装专门的硬件进行负载均衡的工作,F5便为其中的佼佼者。软件负载均衡则是通过在服务器上安装的特定的负载均衡软件或是自带负载均衡模块完成对请求的分配派发。
轮询算法
- 轮循,按公约后的权重设置轮循比率。
- 存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
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]
|
请发表评论