iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Go实现Nginx加权轮询算法的方法是什么
  • 833
分享到

Go实现Nginx加权轮询算法的方法是什么

2023-06-21 23:06:48 833人浏览 泡泡鱼
摘要

本篇文章给大家分享的是有关Go实现Nginx加权轮询算法的方法是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一,Nginx 负载均衡的轮询 (round-robin)在说

本篇文章给大家分享的是有关Go实现Nginx加权轮询算法的方法是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

一,Nginx 负载均衡的轮询 (round-robin)

在说加权轮询之前我们先来简单的说一下轮询

1. nginx 中的配置

upstream cluster {    server 192.168.0.14;    server 192.168.0.15;}location / {   proxy_set_header X-Real-IP $remote_addr;               //返回真实IP   proxy_pass Http://cluster;                           //代理指向cluster     }

2. 简单介绍

轮询 作为负载均衡中较为基础的算法,他的实现不需要配置额外的参数。简单理解:配置文件中一共配置了 N 台服务器,轮询 算法会遍历服务的节点列表,并按照节点顺序每轮选择一台服务器处理请求,当所有节点遍历一遍后,重新开始

3. 特点

轮询 算法中我们不难看出,每台服务器处理请求的数量基本持平,按照请求时间逐一分配,因此只能适用于集群服务器性能相近的情况,平均分配让每台服务器承载量基本持平。但是如果集群服务器性能参差不齐,这样的算法会导致资源分配不合理,造成部分请求阻塞,部分服务器资源浪费。为了解决上述问题,我们将 轮询 算法升级了,引入了 加权轮询 算法,让集群中性能差异较大的服务器也能合理分配资源。达到资源尽量最大化合理利用

4. 实现 (这里使用golang模拟实现)

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    }    curAdd := r.rss[r.curIndex ]    r.curIndex = (r.curIndex + 1) % lens    return curAdd}

5. 测试

简单调用下方法看看结果

func main(){    rb := new(RoundRobinBalance)    rb.Add("127.0.0.1:80")    rb.Add("127.0.0.1:81")    rb.Add("127.0.0.1:82")    rb.Add("127.0.0.1:83")    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())}go run main.go 127.0.0.1:80127.0.0.1:81127.0.0.1:82127.0.0.1:83127.0.0.1:80127.0.0.1:81

二,Nginx 负载均衡的加权轮询 (weighted-round-robin)

进入主题

1. nginx 配置

http {      upstream cluster {          server 192.168.1.2 weight=5;          server 192.168.1.3 weight=3;          server 192.168.1.4 weight=1;      }  location / {       proxy_set_header X-Real-IP $remote_addr;               //返回真实IP       proxy_pass http://cluster;                           //代理指向cluster    }

2. 加权算法简介-特点

不同的服务器的配置,部署的应用数量,网络状况等都会导致服务器处理能力会不一样,所以简单的 轮询 算法将不再适用,而引入 了加权轮询 算法:根据服务器不同的处理能力,给每个服务器分配不同的权值,根据不同的权值将不同的服务器分配到对应的服务器上;

请求数量较大时,每个服务处理请求的数量之比会趋向于权重之比。

3. 算法说明

在 Nginx加权轮询算法 中,每个节点都有3个权重的变量

  • Weight : 配置的权重,根据配置文件初始化每个服务器节点的权重

  • currentWeight : 节点的当前权重,初始化时是配置的权重,随后会一直变更

  • effectiveWeight : 有效的权重,初始值为 weight ,通讯过程中发现节点异常,则 -1 ,之后再次选择本节点,调用成功一次则 +1 ,直到恢复到 weight。这个参数可以用于做降权。或者说是你的设置的权限修正。。

Nginx加权轮询算法 的逻辑实现

  • 轮询所有节点,计算当前状态下所有的节点的 effectiveWeight 之和 作为 totalWeight;

  • 更新每个节点的 currentWeight , currentWeight = currentWeight + effectiveWeight; 选出所有节点 currentWeight 中最大的一个节点作为选中节点;

  • 选择中的节点再次更新 currentWeight, currentWeight = currentWeight - totalWeight;

4. 简单举例

注意:实现中不考虑健康检查,即所有的节点都是100%可用的,所以 effectiveWeight 等于 weight
假设:现在有3个节点 {A, B, C} 分别权重为:{4, 2, 1};请求7次

第N次请求请求前 currentWeight选中的节点请求后 currentWeight
1[serverA=4, serverB=2, serverC=1]serverA[serverA=1, serverB=4, serverC=2]
2[serverA=1, serverB=4, serverC=2]serverB[serverA=5, serverB=-1, serverC=3]
3[serverA=5, serverB=-1, serverC=3]serverA[serverA=2, serverB=1, serverC=4]
4[serverA=2, serverB=1, serverC=4]serverA[serverA=-1, serverB=3, serverC=5]
5[serverA=-1, serverB=3, serverC=5]serverC[serverA=3, serverB=5, serverC=-1]
6[serverA=3, serverB=5, serverC=-1]serverA[serverA=0, serverB=7, serverC=0]
7[serverA=0, serverB=7, serverC=0]serverB[serverA=4, serverB=2, serverC=1]

totaoWeight = 4 + 2 + 1 = 7
第一次请求: serverA = 4 + 4 = 8 , serverB = 2 + 2 = 4, serverC = 1 + 1 = 2; 最大的是 serverA ; 所以选择 serverA ;然后serverA = 8 - 7 = 1;最后得出:serverA=1, serverB=4, serverC=2
第二次请求: serverA = 1 + 4 = 5; serverB = 4 + 2 = 6 ; serverC = 2 + 1 = 3;最大的是 serverB ; 所以选择 serverB ; 然后 serverB = 6 - 7 = -1 ;最后得出: serverA=5, serverB=-1, serverC=3
以此类推。。。

5. 代码实现

以golang实现下上面的逻辑:

type WeightRoundRobinBalance struct {    curIndex int    rss []*Weightnode}type WeightNode struct {    weight int // 配置的权重,即在配置文件或初始化时约定好的每个节点的权重    currentWeight int //节点当前权重,会一直变化    effectiveWeight int //有效权重,初始值为weight, 通讯过程中发现节点异常,则-1 ,之后再次选取本节点,调用成功一次则+1,直达恢复到weight 。 用于健康检查,处理异常节点,降低其权重。    addr string // 服务器addr}func (r *WeightRoundRobinBalance) Add (params ...string) error{    if len(params) != 2{        return errors.New("params len need 2")    }    // @Todo 获取值    addr := params[0]    parInt, err  := strconv.ParseInt(params[1], 10, 64)    if err != nil {        return err    }    node := &WeightNode{        weight: int(parInt),        effectiveWeight: int(parInt),  // 初始化時有效权重 = 配置权重值        currentWeight: int(parInt), // 初始化時当前权重 = 配置权重值        addr: addr,    }    r.rss = append(r.rss, node)    return nil}func (r *WeightRoundRobinBalance) Next () string {    // @Todo 没有服务    if len(r.rss) == 0 {        return ""    }    totalWeight := 0    var maxWeightNode *WeightNode    for key , node  := range r.rss {        // @Todo 计算当前状态下所有节点的effectiveWeight之和totalWeight        totalWeight += node.effectiveWeight        // @Todo 计算currentWeight        node.currentWeight += node.effectiveWeight        // @Todo 寻找权重最大的        if maxWeightNode == nil ||  maxWeightNode.currentWeight < node.currentWeight {            maxWeightNode = node            r.curIndex = key        }    }    // @Todo 更新选中节点的currentWeight    maxWeightNode.currentWeight -= totalWeight    // @Todo 返回addr    return maxWeightNode.addr}

6. 测试验证

func main(){    rb := new(WeightRoundRobinBalance)    rb.Add("127.0.0.1:80", "4")    rb.Add("127.0.0.1:81", "2")    rb.Add("127.0.0.1:82", "1")    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())    fmt.Println(rb.Next())}

执行下看下结果:

run main.go

127.0.0.1:80
127.0.0.1:81
127.0.0.1:80
127.0.0.1:80
127.0.0.1:82
127.0.0.1:80
127.0.0.1:81

以上就是Go实现Nginx加权轮询算法的方法是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网精选频道。

--结束END--

本文标题: Go实现Nginx加权轮询算法的方法是什么

本文链接: https://www.lsjlt.com/news/301524.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Go实现Nginx加权轮询算法的方法是什么
    本篇文章给大家分享的是有关Go实现Nginx加权轮询算法的方法是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一,Nginx 负载均衡的轮询 (round-robin)在说...
    99+
    2023-06-21
  • Java负载均衡算法实现之轮询和加权轮询
    目录1.普通轮询算法2.加权轮询算法2.1.实现方式一2.2.实现方式二(重点难点)2.2.1.概述2.2.2.举个例子理解算法2.2.3.代码实现总结1.普通轮询算法 轮询(Rou...
    99+
    2024-04-02
  • Java实现平滑加权轮询算法之降权和提权详解
    目录前言1.两个关键点2.代码实现2.1.服务节点类2.2.平滑轮询算法降权和提权3.分析结果4.结论前言 上一篇讲了普通轮询、加权轮询的两种实现方式,重点讲了平滑加权轮询算法,并在...
    99+
    2024-04-02
  • android轮播图实现的方法是什么
    Android中轮播图的实现方法一般有以下几种: 使用ViewPager:ViewPager是Android提供的用于实现滑动切...
    99+
    2024-02-29
    android
  • Go实现基于RSA加密算法的接口鉴权
    基于 RSA 加密算法的接口鉴权方案 假设接口调用者是客户端,接口提供方是服务端,则此方案存在以下规则: 客户端需要使用 RSA 算法(1024 位长度的私钥)生成公私钥...
    99+
    2024-04-02
  • css实现图片轮播的方法是什么
    今天小编给大家分享一下css实现图片轮播的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。首先,在页面中创建对个im...
    99+
    2023-07-04
  • LRU缓存算法的实现方法是什么
    这篇文章主要讲解了“LRU缓存算法的实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“LRU缓存算法的实现方法是什么”吧!LRU就是Least R...
    99+
    2024-04-02
  • Java排序算法实现的方法是什么
    这篇文章主要介绍“Java排序算法实现的方法是什么”,在日常操作中,相信很多人在Java排序算法实现的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java排序算法实现的方法是什么”的疑惑有所帮助!...
    99+
    2023-06-02
  • redis加锁的实现方法是什么
    在Redis中实现锁通常使用SET命令来实现,通过设置一个特定的key作为锁,并设置一个过期时间来避免死锁。以下是一种常见的Redi...
    99+
    2024-04-30
    redis
  • JavaScript实现可终止轮询请求的方法
    目录什么是轮询请求?轮询的要点setInterval的问题实现轮询准备工作基础版进阶版最终版最近遇到了一个需求,需要每隔5s请求一个接口获取接口返回的结果,返回成功后停止请求,接口的...
    99+
    2024-04-02
  • nginx添加虚拟主机的方法是什么
    在nginx中添加虚拟主机的方法是通过配置文件进行的。以下是添加虚拟主机的步骤:1. 打开nginx的配置文件。通常位于 `/etc...
    99+
    2023-09-07
    nginx 虚拟主机
  • SpringCloud中Gateway实现鉴权的方法是什么
    本篇内容介绍了“SpringCloud中Gateway实现鉴权的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、JWT 实现微服...
    99+
    2023-06-21
  • SQL实现分页查询的方法是什么
    SQL实现分页查询的方法主要有两种:1. 使用LIMIT和OFFSET关键字:```sqlSELECT * FROM tab...
    99+
    2023-08-15
    SQL
  • linux添加用户权限的方法是什么
    要添加用户权限,可以使用chmod命令。chmod命令用于更改文件或目录的权限。语法如下: chmod [选项] 模式 文件 其中...
    99+
    2024-03-13
    linux
  • Go归并排序算法的实现方法
    目录归并排序的思想归并排序的 Go 代码实现归并排序的时间复杂度今天继续基础排序算法的图解和Go 代码实现,这次分享一个时间复杂度为*** 诶,时间复杂度多少先保密,文末会有分析。这...
    99+
    2024-04-02
  • Java实现常用的三种加密算法是什么
    这篇文章主要为大家展示了“Java实现常用的三种加密算法是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java实现常用的三种加密算法是什么”这篇文章吧。前言编程中常见的加密算法有以下几种,...
    99+
    2023-06-29
  • PHP加盐实现函数的方法是什么
    今天小编给大家分享一下PHP加盐实现函数的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。第一步:生成一个随机的盐值...
    99+
    2023-07-05
  • Java/Go/Python/JS/C基数排序算法的原理与实现方法是什么
    这篇文章主要介绍“Java/Go/Python/JS/C基数排序算法的原理与实现方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java/Go/Python/JS/C基数排序算法的原理与实现...
    99+
    2023-07-05
  • Golang实现四种负载均衡的算法(随机,轮询等)
    随机负载 随机挑选目标服务器 package load_balance import ( "errors" "math/rand" ) //随机负载均衡 type Ran...
    99+
    2024-04-02
  • 在Go中实现分布式算法的技巧是什么?
    随着互联网技术的不断发展,分布式系统已经成为了现代软件开发中必不可少的一部分。在这样的背景下,Go语言也逐渐受到了人们的关注。Go语言作为一门高效、并发性强的语言,非常适合用来实现分布式系统。本文将介绍在Go中实现分布式算法的技巧。 一、...
    99+
    2023-10-08
    编程算法 数组 分布式
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作