负载均衡算法之轮询(Round Robin)法和随机(Random)法 Java 代码实现方法学习

轮询(Round Robin)法

轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。

其代码实现大致如下:

import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.Set;/**
 * @author ashang.peng@aliyun.com
 * @date 二月 07, 2017
 */class RoundRobin   {
    private static Integer pos = 0;

    public static String getServer()
    {        // 重建一个Map,避免服务器的上下线导致的并发问题
        Map<String, Integer> serverMap =                new HashMap<String, Integer>();
        serverMap.putAll(IpMap.serverWeightMap);        // 取得Ip地址List
        Set<String> keySet = serverMap.keySet();
        ArrayList<String> keyList = new ArrayList<String>();
        keyList.addAll(keySet);        String server = null;
        synchronized (pos)
        {            if (pos > keySet.size())
                pos = 0;
            server = keyList.get(pos);
            pos ++;
        }        return server;
    }
}

由于serverWeightMap中的地址列表是动态的,随时可能有机器上线、下线或者宕机,因此为了避免可能出现的并发问题,方法内部要新建局部变量serverMap,现将serverMap中的内容复制到线程本地,以避免被多个线程修改。这样可能会引入新的问题,复制以后serverWeightMap的修改无法反映给serverMap,也就是说这一轮选择服务器的过程中,新增服务器或者下线服务器,负载均衡算法将无法获知。新增无所谓,如果有服务器下线或者宕机,那么可能会访问到不存在的地址。因此,服务调用端需要有相应的容错处理,比如重新发起一次server选择并调用。

对于当前轮询的位置变量pos,为了保证服务器选择的顺序性,需要在操作时对其加锁,使得同一时刻只能有一个线程可以修改pos的值,否则当pos变量被并发修改,则无法保证服务器选择的顺序性,甚至有可能导致keyList数组越界。

轮询法的优点在于:试图做到请求转移的绝对均衡。

轮询法的缺点在于:为了做到请求转移的绝对均衡,必须付出相当大的代价,因为为了保证pos变量修改的互斥性,需要引入重量级的悲观锁synchronized,这将会导致该段轮询代码的并发吞吐量发生明显的下降。

随机(Random)法

通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,

其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。

随机法的代码实现大致如下:

import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.Set;/**
 * @author ashang.peng@aliyun.com
 * @date 二月 07, 2017
 */

 class Random   {
    public static String getServer()
    {        // 重建一个Map,避免服务器的上下线导致的并发问题   
        Map<String, Integer> serverMap =                new HashMap<String, Integer>();
        serverMap.putAll(IpMap.serverWeightMap);        // 取得Ip地址List   
        Set<String> keySet = serverMap.keySet();
        ArrayList<String> keyList = new ArrayList<String>();
        keyList.addAll(keySet);

        java.util.Random random = new java.util.Random();
        int randomPos = random.nextInt(keyList.size());        return keyList.get(randomPos);
    }
}

整体代码思路和轮询法一致,先重建serverMap,再获取到server列表。在选取server的时候,通过Random的nextInt方法取0~keyList.size()区间的一个随机值,从而从服务器列表中随机获取到一台服务器地址进行返回。基于概率统计的理论,吞吐量越大,随机算法的效果越接近于轮询算法的效果。

本文分享自微信公众号 - Java学习网(javalearns)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员宝库

趣图:客户的需求 vs 客户的预算​

35840
来自专栏老九学堂

小心那个深夜秒回你的程序员!

23830
来自专栏张叔叔讲互联网

当妈妈在淘宝购物的时候,都发生了什么?(下篇)

在上一篇文章中,讲到了你的妈妈成功从你手中夺得了电脑的控制权,然后打开了淘宝网并且在网站首页搜索框中搜索了“美丽的裙子”,之后用一种挑剔的眼光盯着电脑屏幕一个多...

16340
来自专栏程序员宝库

程序员培训出身狂揽活,加班被同事嘲笑活该,网友:急于证明自己

俗话说初生牛犊不怕虎,刚进入职场的人在工作上总是充满干劲,这份新鲜血液的注入也会给公司带来新的活力。就有一名培训出身的程序员加入新公司,因为表现过于“耀眼”被同...

20330
来自专栏码字搬砖

一个菜鸟的经验

1.刚毕业或者毕业没多久不要去小公司,特别是没有牛人的小公司,有牛人又有很好前景的小公司可以去 2.基础很重要,基础很重要,基础很重要

10220
来自专栏程序员宝库

趣图:程序员的生活写照

11940
来自专栏眯眯眼猫头鹰的小树杈

猫头鹰的深夜翻译:Pattern: Service Mesh

在十几年前,我们无法想象一个分布式系统会是什么样子。它给我们带来了全新的架构思路,但同时也引入了一些问题。 当时这些系统非常少有而且架构简单,工程师们通过尽可能...

22020
来自专栏老九学堂

有一种桌面,叫程序员的电脑桌面.....

42540
来自专栏非著名程序员

不可思议,我们程序员竟然上热搜了

天气转冷,一支神秘而又强大的力量突然重出江湖。他们是一群思维严谨,着装统一(其实就是撞衫),腰别键盘,双肩背包的人。这股神秘而又庞大的力量充斥在江湖的一线和二线...

12430
来自专栏码农分享

3.2、苏宁百万级商品爬取 思路讲解 商品爬取

如果我要得到A类别的第B页的商品我应该如何拼接符合条件的地址 我们首先分析地址,地址如下

13630

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励