目录

  • 1、引言
  • 2、负载均衡算法
    • 2.1、随机算法(Random)
    • 2.2、加权随机算法(WeightRandom)
    • 2.3、轮询算法(Random)
    • 2.4、加权轮询算法(WeightRoundRobin)
    • 2.5、IP-Hash算法(IpHash)
    • 2.6、最小连接数算法( LeastConnection)

1、引言

负载均衡是我们平时常见的解决高并发问题的一大法宝,负载均衡从字面理解就是将请求均衡分发到后台的服务器,本文通过例子模拟几种常见负载均衡算法的实现。
源码参考:com.leo.demo.loadbalancetes
git地址:https://gitee.com/leo825/sortalgorithm-demos.git

2、负载均衡算法

本文主要介绍一下几种负载均衡算法的实现:

  1. 随机算法
  2. 加权随机算法
  3. 轮询算法
  4. 加权轮询算法
  5. IP-Hash算法
  6. 最小连接数算法
2.1、随机算法(Random)

通过系统随机函数,根据后台服务器的server的地址随机选取其中一台服务器进行访问,根据概率论的相关知识,随着调用量的增加,最终的访问趋于平均,就是达到了均衡的目的。

/*** @author Administrator* @Date 2019/8/20 15:08** 随机法:* 负载均衡方法随机的把负载分配到各个可用的服务器上,通过随机数生成算法选取一个服务器。毕竟随机,,有效性受到了质疑**/
public class TestRandom {//    1.定义map, key-ip,value-weightstatic Map<String,Integer> ipMap=new HashMap<>();static {ipMap.put("192.168.13.1",1);ipMap.put("192.168.13.2",2);ipMap.put("192.168.13.3",4);}public String Random() {Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();ipServerMap.putAll(ipMap);Set<String> ipSet=ipServerMap.keySet();//定义一个list放所有serverArrayList<String> ipArrayList=new ArrayList<String>();ipArrayList.addAll(ipSet);//循环随机数Random random=new Random();//随机数在list数量中取(1-list.size)int pos=random.nextInt(ipArrayList.size());String serverNameReturn= ipArrayList.get(pos);return  serverNameReturn;}public static void main(String[] args) {TestRandom testRandom=new TestRandom();for (int i =0;i<10;i++){String server=testRandom.Random();System.out.println(server);}}
}
2.2、加权随机算法(WeightRandom)

加权随机算法就是在上面的随机算法的基础上做的优化,比如一些性能好的Server多承担一些,请求根据权重分发到各个服务器。

/*** @author Administrator* @Date 2019/8/20 15:11* 加权随机法:* 获取带有权重的随机数字,随机这种东西,不能看绝对,只能看相对。*/
public class TestWeightRandom {//    1.定义map, key-ip,value-weightstatic Map<String, Integer> ipMap = new HashMap<>();static {ipMap.put("192.168.13.1", 1);ipMap.put("192.168.13.2", 2);ipMap.put("192.168.13.3", 4);}public String weightRandom() {Map<String, Integer> ipServerMap = new ConcurrentHashMap<>();ipServerMap.putAll(ipMap);Set<String> ipSet = ipServerMap.keySet();Iterator<String> ipIterator = ipSet.iterator();//定义一个list放所有serverArrayList<String> ipArrayList = new ArrayList<String>();//循环set,根据set中的可以去得知map中的value,给list中添加对应数字的server数量while (ipIterator.hasNext()) {String serverName = ipIterator.next();Integer weight = ipServerMap.get(serverName);for (int i = 0; i < weight; i++) {ipArrayList.add(serverName);}}//循环随机数Random random = new Random();//随机数在list数量中取(1-list.size)int pos = random.nextInt(ipArrayList.size());String serverNameReturn = ipArrayList.get(pos);return serverNameReturn;}public static void main(String[] args) {TestWeightRandom testWeightRandom = new TestWeightRandom();for (int i = 0; i < 10; i++) {String server = testWeightRandom.weightRandom();System.out.println(server);}}
}
2.3、轮询算法(Random)

轮询算法顾名思义,就是按照顺序轮流访问后台服务。

/*** @author Administrator* @Date 2019/8/20 14:34** 轮询法:* 轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器。* 优点:绝对公平* 缺点:无法根据服务器性能去分配,无法合理利用服务器资源。** @TODO*/
public class TestRoundRobin {//1.定义map, key-ip,value-weightstatic Map<String,Integer> ipMap=new HashMap<>();static {ipMap.put("192.168.13.1",1);ipMap.put("192.168.13.2",1);ipMap.put("192.168.13.3",1);}//Integer sum=0;Integer  pos = 0;public String RoundRobin(){Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();ipServerMap.putAll(ipMap);//2.取出来key,放到set中Set<String> ipset=ipServerMap.keySet();//3.set放到list,要循环list取出ArrayList<String> iplist=new ArrayList<String>();iplist.addAll(ipset);String serverName=null;//4.定义一个循环的值,如果大于set就从0开始synchronized(pos){if (pos>=ipset.size()){pos=0;}serverName=iplist.get(pos);//轮询+1pos ++;}return serverName;}public static void main(String[] args) {TestRoundRobin testRoundRobin=new TestRoundRobin();for (int i=0;i<10;i++){String serverIp=testRoundRobin.RoundRobin();System.out.println(serverIp);}}
}
2.4、加权轮询算法(WeightRoundRobin)

加权随机一样,加权轮询,就是在轮询的基础上加上权重,将服务器性能好的,权重高一些。

/*** @author Administrator* @Date 2019/8/20 15:00* 加权轮询法:* 该算法中,每个机器接受的连接数量是按权重比例分配的。这是对普通轮询算法的改进,比如你可以设定:* 第三台机器的处理能力是第一台机器的两倍,那么负载均衡器会把两倍的连接数量分配给第3台机器。加权轮询分为:简单的轮询、平滑的轮询。* 什么是平滑的轮询,就是把每个不同的服务,平均分布。在Nginx源码中,实现了一种叫做平滑的加权轮询(smooth weighted round-robin balancing)* 的算法,它生成的序列更加均匀。5个请求现在分散开来,不再是连续的。*/
public class TestWeightRoundRobin {//1.map, key-ip,value-weightstatic Map<String,Integer> ipMap=new HashMap<>();static {ipMap.put("192.168.13.1",1);ipMap.put("192.168.13.2",2);ipMap.put("192.168.13.3",4);}Integer pos=0;public String weightRoundRobin(){Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();ipServerMap.putAll(ipMap);Set<String> ipSet=ipServerMap.keySet();Iterator<String> ipIterator=ipSet.iterator();//定义一个list放所有serverArrayList<String> ipArrayList=new ArrayList<String>();//循环set,根据set中的可以去得知map中的value,给list中添加对应数字的server数量while (ipIterator.hasNext()){String serverName=ipIterator.next();Integer weight=ipServerMap.get(serverName);for (int i = 0;i < weight ;i++){ipArrayList.add(serverName);}}String serverName=null;if (pos>=ipArrayList.size()){pos=0;}serverName=ipArrayList.get(pos);//轮询+1pos ++;return  serverName;}public static void main(String[] args) {TestWeightRoundRobin testWeightRoundRobin=new TestWeightRoundRobin();for (int i =0;i<10;i++){String server=testWeightRoundRobin.weightRoundRobin();System.out.println(server);}}
}
2.5、IP-Hash算法(IpHash)

根据hash算法,将请求大致均分的分配到各个服务器上

/*** @author Administrator* @Date 2019/8/20 15:13* IP_Hash算法:* hash(object)%N算法,通过一种散列算法把请求分配到不同的服务器上。*/
public class TestIpHash {//    1.定义map, key-ip,value-weightstatic Map<String, Integer> ipMap = new HashMap<>();static {ipMap.put("192.168.13.1", 1);ipMap.put("192.168.13.2", 2);ipMap.put("192.168.13.3", 4);}public String ipHash(String clientIP) {Map<String, Integer> ipServerMap = new ConcurrentHashMap<>();ipServerMap.putAll(ipMap);//2.取出来key,放到set中Set<String> ipset = ipServerMap.keySet();//3.set放到list,要循环list取出ArrayList<String> iplist = new ArrayList<String>();iplist.addAll(ipset);//对ip的hashcode值取余数,每次都一样的int hashCode = clientIP.hashCode();int serverListsize = iplist.size();int pos = hashCode % serverListsize;return iplist.get(pos);}public static void main(String[] args) {TestIpHash testIpHash = new TestIpHash();for(int i = 0; i < 10; i++){System.out.println(testIpHash.ipHash("192.168.21.2"));System.out.println(testIpHash.ipHash("192.168.21.3"));}}}
2.6、最小连接数算法( LeastConnection)

前面我们费尽心思来实现服务消费者请求次数分配的均衡,我们知道这样做是没错的,可以为后端的多台服务器平均分配工作量,最大程度地提高服务器的利用率,但是,实际上,请求次数的均衡并不代表负载的均衡。因此我们需要介绍最小连接数法,最小连接数法比较灵活和智能,由于后台服务器的配置不尽相同,对请求的处理有快有慢,它正是根据后端服务器当前的连接情况,动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能的提高后台服务器利用率,将负载合理的分流到每一台服务器。

/*** @ClassName: TestLeastConnection* @Description: 最小连接数算法* 最小连接数法是根据服务器当前的连接情况进行负载均衡的,当请求到来时,会选取当前连接数最少的一台服务器来处理请求。* @Author: leo825* @Date: 2020-02-11 13:02* @Version: 1.0*/
public class TestLeastConnection {//1.定义map, key-ip,value-weight/*** 定义map* key:模拟后台服务的ip* value:一个Map,map的key是权重,value是接受请求的次数,*/static Map<String, Integer> ipMap = new HashMap<>();//模拟请求的次数static ThreadLocalRandom random = ThreadLocalRandom.current();static {ipMap.put("192.168.13.1", random.nextInt(10));ipMap.put("192.168.13.2", random.nextInt(10));ipMap.put("192.168.13.3", random.nextInt(10));}//从list中选取接受请求数最少的服务并返回public String leastConnection() {Iterator<String> ipListIterator = ipMap.keySet().iterator();String serverName = null;int times = 0;//访问次数while (ipListIterator.hasNext()) {String tmpServerName = ipListIterator.next();int requestTimes = ipMap.get(tmpServerName);//第一次需要赋值if (times == 0) {serverName = tmpServerName;times = requestTimes;} else {//找到最小次数if (times > requestTimes) {serverName = tmpServerName;times = requestTimes;}}}ipMap.put(serverName, ++times);//访问后+1System.out.println("获取到的地址是:" + serverName + ", 访问次数:" + times);return serverName;}public static void main(String[] args) {TestLeastConnection testLeastConnection = new TestLeastConnection();for (int i = 0; i < 10; i++) {testLeastConnection.leastConnection();}}
}

Java代码实现负载均衡六种算法(强烈建议收藏)相关推荐

  1. Java代码实现负载均衡五种算法

    前言: 负载均衡是为了解决并发情况下,多个请求访问,把请求通过提前约定好的规则转发给各个server.其中有好几个种经典的算法.在用java代码编写这几种算法之前,先来了解一下负载均衡这个概念. 1. ...

  2. Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载)

    Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载) 说明:主要是针对一些中大型的项目需要进行分布式以及负载均衡的架构提一些思路与建议. 面对大量用户访问.高并发请求,海量 ...

  3. 传授“带权重的负载均衡实现算法”独家设计思路!

    作者|孙玄/陈东 分布式系统中,大部分系统调用都会涉及到负载均衡,例如:客户端发往服务端的请求首先到达反向代理,然后反向代理再通过负载均衡算法将请求转发到业务系统:或者后端业务系统各模块间的调用前,也 ...

  4. java random算法_负载均衡--随机算法(Random)

    随机算法是指:从服务器列表中,随机选取一台服务器进行访问.由概率论可以得知,随着客户端调用服务端的次数增多,其实际效果趋近于平均分配请求到服务端的每一台服务器,也就是达到轮询的效果. 一.算法描述 假 ...

  5. java架构之-负载均衡-Ribbon 的使用

    一. 什么是负载均衡 负载均衡就是分发请求流量到不同的服务器. 负载均衡一般分为两种: 1. 服务器端负载均衡(nginx) 2. 客户端负载均衡(Ribbon) 二. spring- - cloud ...

  6. SpringCloud- Ribbon 负载均衡 轮训算法

    前言 负载均衡算法: RestTemplate接口请求数 % 服务器集群总数量 = 实际调用服务器的位置下标 过程 // 获取集群中可用服务列表信息 字符串格式List<String> s ...

  7. F5 BIGip 负载均衡 IP算法解密工具

    BIGip是对负载均衡的实现,主要通过Virtual Server.iRules.Pool.Node.Monitor和Persistent(会话保持)实现.BIGip在实现会话保持机制时会在用户首次发 ...

  8. Java程序员必备核心知识点整理,建议收藏!

    说实话,作为一名 Java 程序员,不论你需不需要面试都应该好好看下这份资料.我大概撸了一遍,真的是堪称典范. 就目前国内的面试模式来讲,在面试前积极的准备面试,复习整个 Java 知识体系将变得非常 ...

  9. 一文带你全方位(架构,原理及代码实现)了解Flink(3.2W字建议收藏)

    注:最底部有PDF目录 一 flink简介 1.1 什么是flink Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎.F ...

最新文章

  1. 用Windows Media Player截图的方法
  2. Nokia5110液晶屏完全新手学习笔记(二)
  3. WF流程设计器升级说明
  4. tomcat 和 jdk 版本 对应关系
  5. 收藏!这些 IDE 使用技巧,你都知道吗
  6. Android从url不产生cookie,如何从android.webkit.CookieManager获取所有cookie或cookie的URL
  7. Prototype 框架分析(一)
  8. visio2013复制到word有多余白边_学习工坊(一)|实用技巧之Word篇
  9. python从零开始基础入门——开发环境搭建
  10. anaconda安装好tensorflow后,无法在jupyter notebook上使用的解决方法
  11. IOS 状态栏 显示与隐藏网络活动状态
  12. python_文件处理模式
  13. 统信系统UOS桌面版V20 用户手册
  14. 划片机操作安全注意事项
  15. 数据结构——BF算法
  16. SAI创始人谈美股IPO:做清洁算力领域“特斯拉” 减少碳排放
  17. HTML常用的转义字符汇总
  18. 九度OJ-题目1163:素数
  19. Python+网易企业邮箱发送邮件
  20. 高血糖可以吃哪些零食

热门文章

  1. 年结 利润分配-未分配利润年结
  2. SAP HANA:开启企业管理软件下一波革新浪潮?
  3. 下沉市场消费升级静悄悄?
  4. 拼购电商不是团购,但扎的的却是三四五线城市老百姓的心
  5. mysql截取最后一个斜杠_在MySQL中最后一个斜杠之后选择文本?
  6. node.js 腾讯镜像站_使用腾讯云提供的针对Nuget包管理器的缓存加速服务
  7. matlab里面板有什么作用,MATLAB轻松享受GPU的强大功能
  8. 景观设计主题命名_好听的景观名字
  9. Oracle数据库迁移后变慢,迁移数据之后,读取数据库变得很慢
  10. Python列表的用法和基本操作