写点什么

分布式系统设计之常见的负载均衡算法

作者:Barry Yan
  • 2022-11-15
    北京
  • 本文字数:2440 字

    阅读完需:约 8 分钟

分布式系统设计之常见的负载均衡算法

0 什么是负载均衡?

负载均衡(Load Balance),其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,从而协同完成工作任务。

负载均衡都分为哪些种类?

  • 软件和硬件负载均衡

  • 软件负载均衡

  • 硬件负载均衡

  • 本地和全局负载均衡

  • 本地负载均衡

  • 全局负载均衡


本篇文章的负载均衡算法是属于软件层面的负载均衡。

1 轮询

顾名思义,将子任务在子节点中一个接一个有序的询问请求。


var list = make([]string, 0)var servers = make(map[string]string)
func init() { servers = map[string]string{ "stringA": "10.0.0.1", "stringB": "10.0.0.2", "stringC": "10.0.0.3", } for s := range servers { list = append(list, s) }}
//轮询var i = 0
func RoundRobin() string { if i >= len(list) { i = 0 } str := servers[list[i]] i += 1 return str}
复制代码

2 随机

在子节点中随机的进行请求。


var list = make([]string, 0)var servers = make(map[string]string)
func init() { servers = map[string]string{ "stringA": "10.0.0.1", "stringB": "10.0.0.2", "stringC": "10.0.0.3", } for s := range servers { list = append(list, s) }}
//随机func Random() string { i := rand.Intn(len(list)) return servers[list[i]]}
复制代码

3 加权轮询

与轮询不同的是,可以增加权重,就是说权重最大的节点会有更多次数(比例)的请求。


var list = make([]string, 0)var servers = make(map[string]string)
func init() { servers = map[string]string{ "stringA": "10.0.0.1", "stringB": "10.0.0.2", "stringC": "10.0.0.3", } for s := range servers { list = append(list, s) } //加权轮询 var weight_map = map[string]int{ "stringA": 1, "stringB": 2, "stringC": 3, } for s := range weight_map { for i := 0; i < weight_map[s]-1; i++ { list = append(list, s) } }}
//加权轮询func WeightRoundRobin() string { if i >= len(list) { i = 0 } str := servers[list[i]] i += 1 return str}
复制代码

4 加权随机

与随机不同的是,增加某个节点被随机访问的概率。


var list = make([]string, 0)var servers = make(map[string]string)
func init() { servers = map[string]string{ "stringA": "10.0.0.1", "stringB": "10.0.0.2", "stringC": "10.0.0.3", } for s := range servers { list = append(list, s) } //加权轮询 var weight_map = map[string]int{ "stringA": 1, "stringB": 2, "stringC": 3, } for s := range weight_map { for i := 0; i < weight_map[s]-1; i++ { list = append(list, s) } }}
//加权随机func WeightRandom() string { i := rand.Intn(len(list)) return servers[list[i]]}
复制代码

5 源地址哈希

该方法是将请求的源地址进行哈希,并将哈希的结果进行取余,将取余后的结果进行节点的匹配最后进行请求。


//Source Hashfunc Hash() string {   //对客户端(源)地址做哈希 使用md5哈希算法   has, err := md5.New().Write([]byte("127.0.0.1"))   if err != nil {      panic(err)   }   i := has % len(list)   return servers[list[i]]}
复制代码

6 最小连接数

最小连接数法是根据服务器当前的连接情况进行负载均衡的,当请求到来时,会选取当前连接数最少的一台服务器来处理请求。由此也可以延伸出,根据服务器 CPU 占用最少,根据单位时间内处理请求的效率高低等进行服务器选择。最小连接数法只是动态分配服务器的一种算法,通过各种维度的参数计算,可以找到适合不同场景的更均衡的动态分配服务器的方案。

7 全部代码

package main
import ( "crypto/md5" "math/rand" "net/http")
var list = make([]string, 0)var servers = make(map[string]string)
func init() { servers = map[string]string{ "stringA": "10.0.0.1", "stringB": "10.0.0.2", "stringC": "10.0.0.3", } for s := range servers { list = append(list, s) } //加权轮询 var weight_map = map[string]int{ "stringA": 1, "stringB": 2, "stringC": 3, } for s := range weight_map { for i := 0; i < weight_map[s]-1; i++ { list = append(list, s) } }}
//轮询var i = 0
func RoundRobin() string { if i >= len(list) { i = 0 } str := servers[list[i]] i += 1 return str}
//随机func Random() string { i := rand.Intn(len(list)) return servers[list[i]]}
//Source Hashfunc Hash() string { //对客户端(源)地址做哈希 使用md5哈希算法 has, err := md5.New().Write([]byte("127.0.0.1")) if err != nil { panic(err) } i := has % len(list) return servers[list[i]]}
//加权轮询func WeightRoundRobin() string { if i >= len(list) { i = 0 } str := servers[list[i]] i += 1 return str}
//加权随机func WeightRandom() string { i := rand.Intn(len(list)) return servers[list[i]]}
//----------Web测试---------------//
func main() { //httpServer(WeightRandom)}
func httpServer(fun func() string) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Request Node is " + fun())) }) http.ListenAndServe(":8888", nil)}
复制代码


参考文章:


https://blog.csdn.net/claram/article/details/90290397

发布于: 刚刚阅读数: 3
用户头像

Barry Yan

关注

做兴趣使然的Hero 2021-01-14 加入

Just do it.

评论

发布
暂无评论
分布式系统设计之常见的负载均衡算法_负载均衡_Barry Yan_InfoQ写作社区