Go HttpServer负载均衡之轮训算法的简单模拟
什么是轮询(RoundRobin)?

白话:一个一个轮呗,哈哈哈哈。。。。
效果图:

分析:
利用一个列表或数组之类的存放我们的servers,再用一个变量存放下标,每一次执行一次给下标+1以轮到下一个,最后用servers[小标%len(servers)],这里之所以取模,是为了让下标在servers范围内(不会溢出)。
代码:
package main
import (
"fmt"
"log"
"math/rand"
"net/http"
"net/http/httputil"
"net/url"
"sync"
"time"
)
var servermap = map[int]string{}
var currindex = 0
var lock sync.Mutex
func main() {
servermap[0] = ":9000"
servermap[1] = ":9002"
go server1()
go server2()
http.HandleFunc("/", index)
fmt.Println("Will serve")
http.ListenAndServe(":8088", nil)
}
func index(w http.ResponseWriter, r *http.Request) {
rand.Seed(time.Now().UnixNano())
curr := currindex % len(servermap)
// 保证在servermap列表里面轮训
srv := "http://127.0.0.1" + servermap[curr]
// +1轮之下一次,加锁防止并发导致不能正确轮训
lock.Lock()
currindex++
lock.Unlock()
fmt.Println(srv)
serv, _ := url.Parse(srv)
// 这里通过反向代理模拟真实场景
pro := httputil.NewSingleHostReverseProxy(serv)
pro.ServeHTTP(w, r)
}
// 服务器1
func server1() {
mux1 := http.NewServeMux()
mux1.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("SERVER RUNNING"))
})
server := &http.Server{
Handler: mux1,
Addr: ":9000",
}
log.Println(server.ListenAndServe())
}
// 服务器2
func server2() {
mux2 := http.NewServeMux()
mux2.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("SERVER RUNNING"))
})
server := &http.Server{
Handler: mux2,
Addr: ":9002",
}
log.Println(server.ListenAndServe())
}
以上代码只是一个轮询的简单演示,最重要的学会思路。(由于简单演示,代码方面并不是太严谨。)


本文系作者 @孤独常伴 原创发布在 L0ne1y。未经许可,禁止转载。