diff --git a/http_proxy.go b/fuck/http_proxy.go similarity index 100% rename from http_proxy.go rename to fuck/http_proxy.go diff --git a/main.go b/main.go new file mode 100644 index 0000000..90c55ee --- /dev/null +++ b/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "net/http" + "net/url" + "net/http/httputil" + "log" +) + +var RR = rr.NewWeightedRR(rr.RR_NGINX) + +type handle struct { + addrs []string +} + +func (this *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) { + addr := RR.Next().(string) + remote, err := url.Parse("http://" + addr) + if err != nil { + panic(err) + } + proxy := httputil.NewSingleHostReverseProxy(remote) + proxy.ServeHTTP(w, r) +} + +func startServer() { + //被代理的服务器host和port + h := &handle{} + h.addrs = []string{"172.17.0.2:28080", "172.17.0.3:28080"} + + w := 1 + for _, e := range h.addrs { + RR.Add(e, w) + w++ + } + err := http.ListenAndServe(":28080", h) + if err != nil { + log.Fatalln("ListenAndServe: ", err) + } +} + +func main() { + startServer() +} \ No newline at end of file diff --git a/round_robin.go b/round_robin.go new file mode 100644 index 0000000..2ef7986 --- /dev/null +++ b/round_robin.go @@ -0,0 +1,195 @@ +// RR: 基于 权重round robin算法的接口 +package main + +type RR interface { + Next() interface{} + Add(node interface{}, weight int) + RemoveAll() + Reset() +} + +const ( + RR_NGINX = 0 //Nginx算法 + RR_LVS = 1 //LVS算法 +) + +//算法实现工厂类 +func NewWeightedRR(rtype int) RR { + if rtype == RR_NGINX { + return &WNGINX{} + } else if rtype == RR_LVS { + return &WLVS{} + } + return nil +} + +//节点结构 +type WeightNginx struct { + Node interface{} + Weight int + CurrentWeight int + EffectiveWeight int +} + +func (ww *WeightNginx) fail() { + ww.EffectiveWeight -= ww.Weight + if ww.EffectiveWeight < 0 { + ww.EffectiveWeight = 0 + } +} + +//nginx算法实现类 +type WNGINX struct { + nodes []*WeightNginx + n int +} + +//增加权重节点 +func (w *WNGINX) Add(node interface{}, weight int) { + weighted := &WeightNginx{ + Node: node, + Weight: weight, + EffectiveWeight: weight} + w.nodes = append(w.nodes, weighted) + w.n++ +} + +func (w *WNGINX) RemoveAll() { + w.nodes = w.nodes[:0] + w.n = 0 +} + +//下次轮询事件 +func (w *WNGINX) Next() interface{} { + if w.n == 0 { + return nil + } + if w.n == 1 { + return w.nodes[0].Node + } + + return nextWeightedNode(w.nodes).Node +} + +func nextWeightedNode(nodes []*WeightNginx) (best *WeightNginx) { + total := 0 + + for i := 0; i < len(nodes); i++ { + w := nodes[i] + + if w == nil { + continue + } + + w.CurrentWeight += w.EffectiveWeight + total += w.EffectiveWeight + if w.EffectiveWeight < w.Weight { + w.EffectiveWeight++ + } + + if best == nil || w.CurrentWeight > best.CurrentWeight { + best = w + } + } + + if best == nil { + return nil + } + best.CurrentWeight -= total + return best +} + +func (w *WNGINX) Reset() { + for _, s := range w.nodes { + s.EffectiveWeight = s.Weight + s.CurrentWeight = 0 + } +} + +//节点结构 +type WeightLvs struct { + Node interface{} + Weight int +} + +//lvs算法实现类 +type WLVS struct { + nodes []*WeightLvs + n int + gcd int //通用的权重因子 + maxW int //最大权重 + i int //被选择的次数 + cw int //当前的权重值 +} + +//下次轮询事件 +func (w *WLVS) Next() interface{} { + if w.n == 0 { + return nil + } + + if w.n == 1 { + return w.nodes[0].Node + } + + for { + w.i = (w.i + 1) % w.n + if w.i == 0 { + w.cw = w.cw - w.gcd + if w.cw <= 0 { + w.cw = w.maxW + if w.cw == 0 { + return nil + } + } + } + if w.nodes[w.i].Weight >= w.cw { + return w.nodes[w.i].Node + } + } +} + +//增加权重节点 +func (w *WLVS) Add(node interface{}, weight int) { + weighted := &WeightLvs{Node: node, Weight: weight} + if weight > 0 { + if w.gcd == 0 { + w.gcd = weight + w.maxW = weight + w.i = -1 + w.cw = 0 + } else { + w.gcd = gcd(w.gcd, weight) + if w.maxW < weight { + w.maxW = weight + } + } + } + w.nodes = append(w.nodes, weighted) + w.n++ +} + +func gcd(x, y int) int { + var t int + for { + t = (x % y) + if t > 0 { + x = y + y = t + } else { + return y + } + } +} +func (w *WLVS) RemoveAll() { + w.nodes = w.nodes[:0] + w.n = 0 + w.gcd = 0 + w.maxW = 0 + w.i = -1 + w.cw = 0 +} +func (w *WLVS) Reset() { + w.i = -1 + w.cw = 0 +}