zoukankan      html  css  js  c++  java
  • Golang之实现一个负载均衡算法(随机,轮询)

    代码记录

    程序结构目录

    在这里插入图片描述

    --------程序包

    balance.go

    package balance
    
    type Balancer 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,
        }
    }
    
    //定义Instance结构体的方法GetHost()
    func (p *Instance) GetHost() string {
        return p.host
    }
    
    //定义方法GetPort()
    func (p *Instance) GetPort() int {
        return p.port
    }
    func (p *Instance) String() string {
        return p.host + ":" + strconv.Itoa(p.port)
    }
    

    mgr.go

    package balance
    
    import "fmt"
    
    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) {
        balancer, ok := mgr.allBalancer[name]
        if !ok {
            err = fmt.Errorf("Not found %s balancer", name)
            return
        }
        fmt.Printf("use %s balancer
    ", name)
        inst, err = balancer.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
    }
    

    roundrobin.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]
        p.curIndex = (p.curIndex + 1) % lens
        return
    }
    

    ------入口

    main.go

    package main
    
    import (
        "fmt"
        "../balance"
        "math/rand"
        "os"
        "time"
    )
    
    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)
                fmt.Fprintf(os.Stdout, "do balance err
    ")
                continue
            }
            fmt.Println(inst)
            time.Sleep(time.Second)
        }
    }
    

    hash.go

    package main
    
    import (
        "fmt"
        "../balance"
        "hash/crc32"
        "math/rand"
    )
    
    type HashBalance struct {
        Name string
        Age  int
    }
    
    func init() {
        balance.RegisterBalancer("hash", &HashBalance{})
    }
    func (p *HashBalance) DoBalance(insts []*balance.Instance, key ...string) (inst *balance.Instance, err error) {
        var defKey string = fmt.Sprintf("%d", rand.Int())
        if len(key) > 0 {
            defKey = key[0]
        }
        lens := len(insts)
        if lens == 0 {
            err = fmt.Errorf("No backend instance")
            return
        }
        crcTable := crc32.MakeTable(crc32.IEEE)
        hashVal := crc32.Checksum([]byte(defKey), crcTable)
        index := int(hashVal) % lens
        inst = insts[index]
        return
    }
    
  • 相关阅读:
    ListBox的数据绑定
    GridView中加入新行方法
    一个事务的例子
    用sql语句查询从N条到M条的记录
    用户注册表中日期输入的解决方案
    对分页控件进行分页的封装
    我的触发器
    缓存DataSet以提高性能
    网站访问统计在Global.asax中的配置
    给表格控件绑定数据库内容的封装
  • 原文地址:https://www.cnblogs.com/AlexKing007/p/12338054.html
Copyright © 2011-2022 走看看