负载均衡之加权轮询算法

算法举例说明

服务实例 权重
127.0.0.1:8001 1
127.0.0.1:8002 2
127.0.0.1:8003 3

共有三个实例,总权重为6,那么实现效果应该为每调用6次:

  • 每个实例应该被调用权重次数
  • 权重数大的优先被调用

根据以上说明,那么进行排列组合:

  • 先按照权重大小排序
  • 把权重数做为调用次数排列

排列的结果是这样的:

序号 服务实例 权重
1 127.0.0.1:8003 3
2 127.0.0.1:8003 3
3 127.0.0.1:8003 3
4 127.0.0.1:8002 2
5 127.0.0.1:8002 2
6 127.0.0.1:8001 1

貌似没问题,但每个实例调用不是交替的,分布不够均匀,改进一下重新排列组合:

序号 服务实例 权重
1 127.0.0.1:8003 3
2 127.0.0.1:8002 2
3 127.0.0.1:8003 3
4 127.0.0.1:8002 2
5 127.0.0.1:8003 3
6 127.0.0.1:8001 1

或者

序号 服务实例 权重
1 127.0.0.1:8003 3
2 127.0.0.1:8002 2
3 127.0.0.1:8003 3
4 127.0.0.1:8001 1
5 127.0.0.1:8003 3
6 127.0.0.1:8002 2

2个权重变量:weight,current_weight

weight

配置的固定不变的权重

current_weight

会动态调整的权重,初始化为0,运行时动态调整。
选取开始时,先重新调整current_weight= current_weight+weight,然后通过current_weight值从大到小排序,选择current_weight值最大的(实际编程中不一定要排序,可以直接取最大的);
然后重新计算被选择的current_weight值= current_weight-总weight。

下面是用Lua脚本实现的该算法:


function _M:next()
   local servers=self.servers
   local totalWeight = totalWeight(servers)
   for k,v in pairs(servers) do
       v.cweight=v.weight+v.cweight
   end

   table.sort( servers, 
       function (a,b)
           return a.cweight>b.cweight
       end 
   )
   selected=servers[1]
   selected.cweight=selected.cweight-totalWeight

   return selected

end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 首页 资讯 文章 资源 小组 相亲 登录 注册 首页 最新文章 IT 职场 前端 后端 移动端 数据库 运维 其他...
    Helen_Cat阅读 9,340评论 1 10
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,426评论 11 349
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,307评论 19 139
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 10,585评论 0 52
  • 出来倒饬倒饬
    坚定的柔软阅读 832评论 0 0