zoukankan      html  css  js  c++  java
  • Nginx加权轮询算法

    记录一下nginx加权分配算法。

    nginx可以指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
    例如:

    upstream backend {
      server a weight=6;
      server b weight=3;
      server c weight=1;
    }
    

    按照配置,每有10次请求,其中6个会转发到a服务器,3个转发到b服务器,1个转发到c服务器。

    每个服务器都有三个权重变量,先解释下它们的含义。

    (1) weight

    配置文件中指定的该服务器的权重,这个值是固定不变的。

    (2) effective_weight

    服务器的有效权重,初始值为weight。

    在释放服务器时,如果发现和某服务器的通信过程中发生了错误,就减小它的effective_weight。
    此后有新的请求过来时,在选取该服务器的过程中,再逐步增加effective_weight,最终又恢复到weight。
    之所以增加这个字段,是为了当服务器发生错误时,降低其权重。

    (3) current_weight

    服务器目前的权重,初始为0,之后会动态调整。

    那么如何动态调整呢?

    nginx每次选取服务器时:

    1. 先遍历集群中所有服务器,将每个服务器的current_weight增加它的effective_weight,
    2. 再累加所有服务器的effective_weight,保存为total。
    3. 判断当前服务器的current_weight是否最大,是则选中该服务器,然后把它的current_weight减去total。不是则不会被选中,current_weight也就不用减了。

    弄清了三个weight字段的含义后,加权轮询算法可描述为:

    1. 对于每个请求,遍历集群中的所有可用服务器,对于每个服务器执行:current_weight += effecitve_weight。
    2. 累加所有effective_weight,保存为total。
    3. 选出current_weight最大的服务器,作为本次选定的服务器。
    4. 对于本次选定的服务器,执行:current_weight -= total。

    下面以表格形式记录其过程:

    请求次数 开始current_weight 增加effective_weight 累加total 选中服务器 选中后current_weight
    1 [0, 0, 0] [6, 3, 1] 10 a [-4, 3, 1]
    2 [-4, 3, 1] [2, 6, 2] 10 b [2, -4, 2]
    3 [2, -4, 2] [8, -1, 3] 10 a [-2, -1, 3]
    4 [-2, -1, 3] [4, 2, 4] 10 a [-6, 2, 4]
    5 [-6, 2, 4] [0, 5, 5] 10 b [0, -5, 5]
    6 [0, -5, 5] [6, -2, 6] 10 a [-4, -2, 6]
    7 [-4, -2, 6] [2, 1, 7] 10 c [2, 1, -3]
    8 [2, 1, -3] [8, 4, -2] 10 a [-2, 4, -2]
    9 [-2, 4, -2] [4, 7, -1] 10 b [4, -3, -1]
    10 [4, -3, -1] [10, 0, 0] 10 a [0, 0, 0]

    可以看到,选中服务器依次为[a, b, a, a, b, a, c, a, b, a]。

    a,b,c分别被选中了6,3,1次,正好是符合其权重值的;
    服务器a虽然权重大,但没有被连续选取,不会对a服务器连续请求;
    经过10次请求后,a,b,c的当前权重current_weight又全部归0,如此便可循环往复。

    ps: 这里我们发现total永远都是10,因为这里假定服务器都没有发生故障或返回错误,其effective_weight不变。实际中如果服务器发生了错误,nginx当然也会进行降权处理,total也会变啦。这里我们学习一下正常算法,出错的情况就先不展开了。

  • 相关阅读:
    SVN错误:Attempted to lock an already-locked dir
    DecimalFormat 中的 # 与 0 的区别(中文帮助文档中翻译可能是错误的)
    Logger.getLogger和LogFactory.getLog的区别
    在做excel导出时如何将excel直接写在输出流中
    10 -- 深入使用Spring -- 5... 实现任务的自动调度
    8 -- 深入使用Spring -- 8...2 管理Hibernate的SessionFactory
    8 -- 深入使用Spring -- 8...1 Spring提供的DAO支持
    8 -- 深入使用Spring -- 8... Spring整合Hibernate
    8 -- 深入使用Spring -- 7...4 使用自动装配
    8 -- 深入使用Spring -- 7...3 让Spring管理控制器
  • 原文地址:https://www.cnblogs.com/tenny-peng/p/11532019.html
Copyright © 2011-2022 走看看