实现一个简单负载均衡调度算法,支持随机、轮训、hash等算法

package balance
import(
	"errors"
	"math/rand"
)
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
}
func (p *Instance) String() string{ //设置打印格式
	return p.host + ":" + strconv.Itoa(p.port)
}
type Balancer interface{
	DoBalance([]*Instance, ...string)(*Instance,error) //返回一个实例
}

func init(){ //用于BalanceMgr
	RegisterBalancer("random", &RandomBalance{})
}
type RandomBalance struct{
}

func (p *RandomBalace) 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
}   

func init(){ //用于BalanceMgr
	RegisterBalancer("roundrobin", &RoundRobinBalance{})
}
type RoundRobinBalance struct{ //轮询
	curIndex int
}

func (p *RoundRobinBalace) DoBalance(insts []*Instance, key ...string)(inst *Instance,err error){ //实现方法
	if len(insts) == 0 {
		err = errors.New("No instance")
		return
	}
	lens := len(insts)
	inst = insts[p,curIndex]
	p.curIndex = (p.curIndex + 1) % lens
	return
}   


package main
import(
	"balance"   //balance文件位置 注意/不是\
)
func main(){
	insts := make([]*balance.Instance)  //切片 var insts []*balance.Instance
	for i := 0; i < 16; i++{
		host := fmt.Sprintln("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(insts)
		if err != nil{
			fmt.Println("do balance err:", err)
			continue
		}
		fmt.Println(inst)
		time.Sleep(time.Second)  //调整速度
	}
}


//管理所有的负载均衡算法
package balance

type BalanceMgr struct{
	allBalancer map[string]Balancer
}
var mgr = BalanceMgr{
	allBalancer: make(map[string]Balancer)//初始化
}
func (p *BalanceMgr) registerBalancer(name string, b Balancer){
	p.allBalancer[name] = b
}
func RegisterBalancer(name string, b Balancer){
	mgr.registerBalancer(name, b)
}
func DoBalance(name string, insts []*Instance)(inst *Instance, err error){   //输入指定balance算法
	balancer, ok := mgr.allBalancer[name]
	if !ok{
		err = fmt.Errorf("Not found %s balancer", name)
		return
	}
	fmt.Printf("use %s balancer\n", name)
	inst, err = balancer.DoBalance(insts)
	return
}

扩展实现自己的一个利用hash的调度算法,不用改调用方代码

package main
import "balance"
type HashBalance struct{
}
func init(){
	balance.RegisterBalance("hash", &HashBalance{})
}
func (p *HashBalance) DoBalance(insts []*balance.Instance, key ...string){
	var defKey string = fmt.Sprintf("%d", rand.Int())//默认的key
	if len(key) > 0{
		defKey =key[0]
	}
	lens := len(insts) //后端实例个数
	if lens == 0{
		err = fmt.Println("No backend instance")
		return
	}
	crcTable := crc32.MakeTable(crc32.IEEE)//计算hash
	hashVal := crc32.Checksum([]byte(key[0], crcTable))//可变参数
	index := int(hashVal) % lens //类似一致性hash,用crc64int越界
	inst = insts[index]
	return
}