加权随机算法实现负载均衡

魏莉的微 2019-12-19

加权随机算法实现负载均衡

package util

import (
    "fmt"
    "hash/crc32"
    "math/rand"
    "time"
)

type HttpServer struct { //目标server类
    Host   string
    Weight int
}

func NewHttpServer(host string, weight int) *HttpServer {
    return &HttpServer{Host: host, Weight: weight}
}

type LoadBalance struct { //负载均衡类
    Servers []*HttpServer
}

func NewLoadBalance() *LoadBalance {
    return &LoadBalance{Servers: make([]*HttpServer, 0)}
}

func (this *LoadBalance) AddServer(server *HttpServer) {
    this.Servers = append(this.Servers, server)
}

func (this *LoadBalance) SelectForRand() *HttpServer {
    rand.Seed(time.Now().UnixNano())
    index := rand.Intn(len(this.Servers)) //这里因为权重表为15个1和5个0组成,所以产生0到19的随机数
    return this.Servers[ServerIndices[index]] //通过随机数的索引获得服务器索引进而获得地址
}

func (this *LoadBalance) SelectByIpHash(ip string) *HttpServer {
    index := int(crc32.ChecksumIEEE([]byte(ip))) % len(this.Servers) //通过取余永远index都不会大于this.servers的长度
    return this.Servers[index]
}

func (this *LoadBalance) SelectByWeight(ip string) *HttpServer { //加权随机算法
    rand.Seed(time.Now().UnixNano())
    index := rand.Intn(len(ServerIndices))
    return this.Servers[index]
}

var LB *LoadBalance
var ServerIndices []int

func init() {
    LB := NewLoadBalance()
    LB.AddServer(NewHttpServer("http://localhost:8001/web1", 5))  //web1
    LB.AddServer(NewHttpServer("http://localhost:8002/web2", 15)) //web2
    for index, server := range LB.Servers {
        if server.Weight > 0 {
            for i := 0; i < server.Weight; i++ {
                ServerIndices = append(ServerIndices, index)
            }
        }
    }
    fmt.Println(ServerIndices)
}

调用算法

package main

import (
    "log"
    "net/http"
    "net/http/httputil"
    url2 "net/url"
    "os"
    "os/signal"
    "反向代理/util"
)

type ProxyHandler struct {
}

func (*ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    defer func() {
        if err := recover(); err != nil {
            w.WriteHeader(500)
            log.Println(err)
        }
    }()

    url, _ := url2.Parse(util.LB.SelectByWeight(r.RemoteAddr).Host) //调用加权随机算法
    proxy := httputil.NewSingleHostReverseProxy(url)
    proxy.ServeHTTP(w, r)
}

func main() {
    http.ListenAndServe(":8080", &ProxyHandler{})
    c := make(chan os.Signal)
    signal.Notify(c, os.Interrupt)
    s := <-c
    log.Println(s)

}




相关推荐