魏莉的微 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) }