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

    代码记录

    程序结构目录

    --------程序包

    package balance
    
    type Balancer interface {
        DoBalance([]*Instance, ...string) (*Instance, error)
    }
    balance.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)
    }
    instance.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
    }
    mgr.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
    }
    random.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
    }
    roundrobin.go

    ------入口

    package main
    
    import (
        "fmt"
        "go_dev/day7/example/example1/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)
        }
    }
    main.go
    package main
    
    import (
        "fmt"
        "go_dev/day7/example/example1/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
    }
    hash.go
  • 相关阅读:
    SD卡的控制方法(指令集和控制时序)
    MDK的优化应用(转)
    SD卡的SPI模式的初始化顺序(转)
    SD卡读写扇区注意事项(转)
    MDK下调试时提示AXF文件无法导入的解决方法(转)
    把一个 int 数字 n 格式化成16进制的字符串(前面补零成0位)
    DB9 公头母头引脚定义及连接、封装
    RS232 DB9 公头 母头 串口引脚定义
    Codeforces 91C Ski Base 加边求欧拉回路数量
    Cocos Code IDE + Lua初次使用FastTiledMap的坑
  • 原文地址:https://www.cnblogs.com/pyyu/p/8295590.html
Copyright © 2011-2022 走看看