文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java 进阶之深入理解负载均衡的 5 种算法实现原理

2024-12-02 18:55

关注

前言

什么是负载均衡:

指由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助。通过某种 负载分担技术,将外部发送来的请求均匀分配到对称结构中的某一台服务器上,而接收到请求的服务器独立地回应客户的请求。负载均衡能够平均分配客户请求到服 务器阵列,借此提供快速获取重要数据,解决大量并发访问服务问题,这种集群技术可以用最少的投资获得接近于大型主机的性能;

今天我们就来说说;

一、负载均衡算法简介

1、轮询法

将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载;

2、随机法

通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多, 其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果;

3、源地址哈希法

源地址哈希的思想是根据获取客户端的IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问;

4、加权轮询法

不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端;

5、加权随机法

与加权轮询法一样,加权随机法也根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序;

二、代码实现负载均衡五种算法

1.轮询法

  1. import java.util.*; 
  2. import java.util.concurrent.ConcurrentHashMap; 
  3. public class TestRoundRobin {  
  4.     // 1.定义map, key-ip,value-weight 
  5.     static Map ipMap=new HashMap<>(); 
  6.     static { 
  7.         ipMap.put("192.168.13.1",1); 
  8.         ipMap.put("192.168.13.2",1); 
  9.         ipMap.put("192.168.13.3",1); 
  10.     } 
  11.   // Integer sum=0; 
  12.     Integer  pos = 0
  13.     public String RoundRobin(){ 
  14.         Map ipServerMap=new ConcurrentHashMap<>(); 
  15.         ipServerMap.putAll(ipMap); 
  16.         // 2.取出来key,放到set中 
  17.         Set ipset=ipServerMap.keySet(); 
  18.         // 3.set放到list,要循环list取出 
  19.         ArrayList iplist=new ArrayList(); 
  20.         iplist.addAll(ipset); 
  21.         String serverName=null
  22.         // 4.定义一个循环的值,如果大于set就从0开始 
  23.         synchronized(pos){ 
  24.             if (pos>=ipset.size()){ 
  25.                 pos=0
  26.             } 
  27.             serverName=iplist.get(pos); 
  28.             //轮询+1 
  29.             pos ++; 
  30.         } 
  31.         return serverName; 
  32.     } 
  33.     public static void main(String[] args) { 
  34.         TestRoundRobin testRoundRobin=new TestRoundRobin(); 
  35.         for (int i=0;i<10;i++){ 
  36.             String serverIp=testRoundRobin.RoundRobin(); 
  37.             System.out.println(serverIp); 
  38.         } 
  39.     } 

2.加权轮询法

  1. import java.util.*; 
  2. import java.util.concurrent.ConcurrentHashMap; 
  3. public class TestWeightRobin { 
  4.     //    1.map, key-ip,value-weight 
  5.     static Map ipMap=new HashMap<>(); 
  6.     static { 
  7.         ipMap.put("192.168.13.1",1); 
  8.         ipMap.put("192.168.13.2",2); 
  9.         ipMap.put("192.168.13.3",4); 
  10.     } 
  11.     Integer pos=0
  12.     public String WeightRobin(){ 
  13.         Map ipServerMap=new ConcurrentHashMap<>(); 
  14.         ipServerMap.putAll(ipMap); 
  15.         Set ipSet=ipServerMap.keySet(); 
  16.         Iterator ipIterator=ipSet.iterator(); 
  17.         //定义一个list放所有server 
  18.         ArrayList ipArrayList=new ArrayList(); 
  19.         //循环set,根据set中的可以去得知map中的value,给list中添加对应数字的server数量 
  20.         while (ipIterator.hasNext()){ 
  21.             String serverName=ipIterator.next(); 
  22.             Integer weight=ipServerMap.get(serverName); 
  23.             for (int i = 0;i < weight ;i++){ 
  24.                 ipArrayList.add(serverName); 
  25.             } 
  26.         } 
  27.         String serverName=null
  28.         if (pos>=ipArrayList.size()){ 
  29.             pos=0
  30.         } 
  31.         serverName=ipArrayList.get(pos); 
  32.         //轮询+1 
  33.         pos ++; 
  34.         return  serverName; 
  35.     } 
  36.     public static void main(String[] args) { 
  37.         TestWeightRobin testWeightRobin=new TestWeightRobin(); 
  38.         for (int i =0;i<10;i++){ 
  39.             String server=testWeightRobin.WeightRobin(); 
  40.             System.out.println(server); 
  41.         } 
  42.     } 

3.随机法

  1. import java.util.*; 
  2. import java.util.concurrent.ConcurrentHashMap; 
  3. public class TestRandom { 
  4.     //    1.定义map, key-ip,value-weight 
  5.     static Map ipMap=new HashMap<>(); 
  6.     static { 
  7.         ipMap.put("192.168.13.1",1); 
  8.         ipMap.put("192.168.13.2",2); 
  9.         ipMap.put("192.168.13.3",4); 
  10.     } 
  11.     public String Random() { 
  12.         Map ipServerMap=new ConcurrentHashMap<>(); 
  13.         ipServerMap.putAll(ipMap); 
  14.         Set ipSet=ipServerMap.keySet(); 
  15.         //定义一个list放所有server 
  16.         ArrayList ipArrayList=new ArrayList(); 
  17.         ipArrayList.addAll(ipSet); 
  18.         //循环随机数 
  19.         Random random=new Random(); 
  20.         //随机数在list数量中取(1-list.size) 
  21.         int pos=random.nextInt(ipArrayList.size()); 
  22.         String serverNameReturn= ipArrayList.get(pos); 
  23.         return  serverNameReturn; 
  24.     } 
  25.     public static void main(String[] args) { 
  26.         TestRandom testRandom=new TestRandom(); 
  27.         for (int i =0;i<10;i++){ 
  28.             String server=testRandom.Random(); 
  29.             System.out.println(server); 
  30.         } 
  31.     } 

4.加权随机

  1. import java.util.*; 
  2. import java.util.concurrent.ConcurrentHashMap; 
  3. public class TestRobinRandom { 
  4.     //    1.定义map, key-ip,value-weight 
  5.     static Map ipMap=new HashMap<>(); 
  6.     static { 
  7.         ipMap.put("192.168.13.1",1); 
  8.         ipMap.put("192.168.13.2",2); 
  9.         ipMap.put("192.168.13.3",4); 
  10.     } 
  11.     public String RobinRandom(){ 
  12.         Map ipServerMap=new ConcurrentHashMap<>(); 
  13.         ipServerMap.putAll(ipMap); 
  14.         Set ipSet=ipServerMap.keySet(); 
  15.         Iterator ipIterator=ipSet.iterator(); 
  16.         //定义一个list放所有server 
  17.         ArrayList ipArrayList=new ArrayList(); 
  18.         //循环set,根据set中的可以去得知map中的value,给list中添加对应数字的server数量 
  19.         while (ipIterator.hasNext()){ 
  20.             String serverName=ipIterator.next(); 
  21.             Integer weight=ipServerMap.get(serverName); 
  22.             for (int i=0;i
  23.                 ipArrayList.add(serverName); 
  24.             } 
  25.         } 
  26.         //循环随机数 
  27.         Random random=new Random(); 
  28.         //随机数在list数量中取(1-list.size) 
  29.         int pos=random.nextInt(ipArrayList.size()); 
  30.         String serverNameReturn= ipArrayList.get(pos); 
  31.         return  serverNameReturn; 
  32.     } 
  33.     public static void main(String[] args) { 
  34.         TestRobinRandom testRobinRandom=new TestRobinRandom(); 
  35.         for (int i =0;i<10;i++){ 
  36.             String server=testRobinRandom.RobinRandom(); 
  37.             System.out.println(server); 
  38.         } 
  39.     } 

5.源地址哈希法

  1. import java.util.ArrayList; 
  2. import java.util.HashMap; 
  3. import java.util.Map; 
  4. import java.util.Set; 
  5. import java.util.concurrent.ConcurrentHashMap; 
  6. public class ipHash { 
  7.     //    1.定义map, key-ip,value-weight 
  8.     static Map ipMap=new HashMap<>(); 
  9.     static { 
  10.         ipMap.put("192.168.13.1",1); 
  11.         ipMap.put("192.168.13.2",2); 
  12.         ipMap.put("192.168.13.3",4); 
  13.     } 
  14.     public String ipHash(String clientIP){ 
  15.         Map ipServerMap=new ConcurrentHashMap<>(); 
  16.         ipServerMap.putAll(ipMap); 
  17.         //    2.取出来key,放到set中 
  18.         Set ipset=ipServerMap.keySet(); 
  19.         //    3.set放到list,要循环list取出 
  20.         ArrayList iplist=new ArrayList(); 
  21.         iplist.addAll(ipset); 
  22.         //对ip的hashcode值取余数,每次都一样的 
  23.         int hashCode=clientIP.hashCode(); 
  24.         int serverListsize=iplist.size(); 
  25.         int pos=hashCode%serverListsize; 
  26.         return iplist.get(pos); 
  27.     } 
  28.     public static void main(String[] args) { 
  29.         ipHash iphash=new ipHash(); 
  30.         String servername= iphash.ipHash("192.168.21.2"); 
  31.         System.out.println(servername); 
  32.     } 

总结

不进则退,一起加油

 

来源:Android开发编程内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯