Go接口练习之负载均衡算法

背景

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)
	}
}
发布了32 篇原创文章 · 获赞 16 · 访问量 4702

猜你喜欢

转载自blog.csdn.net/weixin_44879611/article/details/104174902