登录
首页 >  Golang >  Go教程

Golang实现四种负载均衡的算法(随机,轮询等)

来源:脚本之家

时间:2023-01-07 11:44:19 205浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《Golang实现四种负载均衡的算法(随机,轮询等)》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

随机负载

随机挑选目标服务器

package load_balance

import (
 "errors"
 "math/rand"
)

//随机负载均衡
type RandomBalance struct {
 curIndex int

 rss []string
}

func (r *RandomBalance) Add(params ...string) error {
 if len(params) == 0 {
  return errors.New("params len 1 at least")
 }
 addr := params[0]
 r.rss = append(r.rss, addr)

 return nil
}

func (r *RandomBalance) Next() string {
 if len(r.rss) == 0 {
  return ""
 }
 r.curIndex = rand.Intn(len(r.rss))
 return r.rss[r.curIndex]
}

func (r *RandomBalance) Get(string) (string, error) {
 return r.Next(), nil
}

轮询负载

服务器依次轮询

package load_balance

import "errors"

//轮询负载均衡
type RoundRobinBalance struct {
 curIndex int
 rss      []string
}

func (r *RoundRobinBalance) Add(params ...string) error {
 if len(params) == 0 {
  return errors.New("params len 1 at least")
 }

 addr := params[0]
 r.rss = append(r.rss, addr)
 return nil
}

func (r *RoundRobinBalance) Next() string {
 if len(r.rss) == 0 {
  return ""
 }
 lens := len(r.rss)
 if r.curIndex >= lens {
  r.curIndex = 0
 }

 curAddr := r.rss[r.curIndex]
 r.curIndex = (r.curIndex + 1) % lens
 return curAddr
}

func (r *RoundRobinBalance) Get(string) (string, error) {
 return r.Next(), nil
}

加权轮询负载

给目标设置访问权重,按照权重轮询

package load_balance

import (
 "errors"
 "strconv"
)

type WeightRoundRobinBalance struct {
 curIndex int
 rss      []*WeightNode
 rsw      []int
}

type WeightNode struct {
 addr            string
 Weight          int //初始化时对节点约定的权重
 currentWeight   int //节点临时权重,每轮都会变化
 effectiveWeight int //有效权重, 默认与weight相同 , totalWeight = sum(effectiveWeight)  //出现故障就-1
}

//1, currentWeight = currentWeight + effectiveWeight
//2, 选中最大的currentWeight节点为选中节点
//3, currentWeight = currentWeight - totalWeight

func (r *WeightRoundRobinBalance) Add(params ...string) error {
 if len(params) != 2 {
  return errors.New("params len need 2")
 }
 parInt, err := strconv.ParseInt(params[1], 10, 64)
 if err != nil {
  return err
 }
 node := &WeightNode{
  addr:   params[0],
  Weight: int(parInt),
 }
 node.effectiveWeight = node.Weight
 r.rss = append(r.rss, node)
 return nil
}

func (r *WeightRoundRobinBalance) Next() string {
 var best *WeightNode
 total := 0
 for i := 0; i  best.currentWeight {
   best = w
  }
 }

 if best == nil {
  return ""
 }
 //5 变更临时权重为 临时权重-有效权重之和
 best.currentWeight -= total
 return best.addr
}

func (r *WeightRoundRobinBalance) Get(string) (string, error) {
 return r.Next(), nil
}

func (r *WeightRoundRobinBalance) Update()  {

}

一致性hash

请求固定的URL访问指定的IP

package load_balance

import (
 "errors"
 "hash/crc32"
 "sort"
 "strconv"
 "sync"
)

//1 单调性(唯一) 2平衡性 (数据 目标元素均衡) 3分散性(散列)
type Hash func(data []byte) uint32

type UInt32Slice []uint32

func (s UInt32Slice) Len() int {
 return len(s)
}

func (s UInt32Slice) Less(i, j int) bool {
 return s[i] = hash })

 // 如果查找结果 大于 服务器节点哈希数组的最大索引,表示此时该对象哈希值位于最后一个节点之后,那么放入第一个节点中
 if idx == len(c.keys) {
  idx = 0
 }
 c.mux.RLock()
 defer c.mux.RUnlock()
 return c.hashMap[c.keys[idx]], nil
}

封装

定义LoadBalance接口

package load_balance

type LoadBalance interface {
 Add(...string) error
 Get(string)(string, error)

}

工厂方法

package load_balance

type LbType int

const (
 LbRandom LbType = iota
 LbRoundRobin
 LbWeightRoundRobin
 LbConsistentHash
)

func LoadBalanceFactory(lbType LbType) LoadBalance {
 switch lbType {
 case LbRandom:
  return &RandomBalance{}
 case LbConsistentHash:
  return NewConsistentHashBalance(10, nil)
 case LbRoundRobin:
  return &RoundRobinBalance{}
 case LbWeightRoundRobin:
  return &WeightRoundRobinBalance{}
 default:
  return &RandomBalance{}
 }
}

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表