背景
Web请求中,申请服务,为了避免多个服务都集中运行在一个服务器上,于是有了负载均衡,本文撰写了随机算法和轮渡(顺序)算法
balance包
balance.go
package balance
// 负载均衡接口
type Balance interface{
DoBalance([]*Instance,...string) (*Instance,error)
}
Instance.go
package balance
import(
"strconv"
)
// 实例:主机 端口
type Instance struct{
host string
port int
}
// 构造函数
func NewInstance(host string,port int)*Instance {
return &Instance{
host:host,
port:port,
}
}
// 获取主机
func (p *Instance)GetHost()string {
return p.host
}
// 获取端口
func (p *Instance)GetPort()int {
return p.port
}
// 重写打String用于打印
func (p *Instance)String()string {
return p.host + ":" + strconv.Itoa(p.port)
}
mgr.go
package balance
import(
"fmt"
)
// 管理员
type BalanceMgr struct{
// 全部的负载均衡算法 都放在了map里面
allBalancer map[string]Balance
}
// 实例化一个管理员
var mgr = BalanceMgr{
// 初始化map
allBalancer:make(map[string]Balance),
}
// 注册一个负载均衡算法
func (p *BalanceMgr)registerBalancer(name string,b Balance) {
p.allBalancer[name] = b
}
// 注册一个负载均衡算法
func RegisterBalancer(name string,b Balance) {
mgr.registerBalancer(name,b)
}
// ???
func DoBalance(name string,insts []*Instance) (inst *Instance,err error) {
balance,ok:=mgr.allBalancer[name]
if !ok{
err = fmt.Errorf("Not found %s balancer",name)
return
}
fmt.Printf("use %s balancer\n",name)
inst,err = balance.DoBalance(insts)
return
}
random.go
package balance
import(
"errors"
"math/rand"
)
// 初始化函数 用来注册
func init(){
RegisterBalancer("random",&RandomBalance{})
}
// 随机调度
type RandomBalance struct{
}
// 实现接口
func (p *RandomBalance) DoBalance(insts []*Instance,key ...string) (inst *Instance,err error){
if len(insts) == 0{
err = errors.New("No Instance")
return
}
lens := len(insts)
index := rand.Intn(lens)
inst =insts[index]
return
}
randrobin.go
package balance
import(
"errors"
)
// 初始化函数 用来注册
func init(){
RegisterBalancer("roundrobin",&RoundRobinBalance{})
}
// 顺序调度
type RoundRobinBalance struct{
curIndex int
}
// 实现接口
func (p *RoundRobinBalance) DoBalance(insts []*Instance,key...string) (inst *Instance,err error){
if len(insts) == 0{
err = errors.New("No Instance")
return
}
lens := len(insts)
if p.curIndex >= lens {
p.curIndex = 0
}
inst = insts[p.curIndex]
return
}
入口函数
main.go
package main
import(
"go_dev/day06/work/balance"
"fmt"
"time"
"math/rand"
"os"
)
func main() {
var insts []*balance.Instance
for i := 0; i<16;i++{
host := fmt.Sprintf("192.168.%d,%d",rand.Intn(255),rand.Intn(255))
one :=balance.NewInstance(host,8080)
insts = append(insts,one)
}
// 根据不同配置选择不同负载均衡算法
var balanceName = "random"
if len(os.Args) > 1 {
balanceName = os.Args[1]
}
// 模拟请求
for{
// 不断执行,变量覆写接口的内容
inst,err:=balance.DoBalance(balanceName,insts)
if err !=nil{
fmt.Println("do balance err:",err)
continue
}
fmt.Println(inst)
time.Sleep(time.Second)
}
}