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

开发 后端 算法
负载均衡能够平均分配客户请求到服 务器阵列,借此提供快速获取重要数据,解决大量并发访问服务问题,这种集群技术可以用最少的投资获得接近于大型主机的性能。

 

前言

什么是负载均衡:

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

今天我们就来说说;

一、负载均衡算法简介

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<String,Integer> 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<String,Integer> ipServerMap=new ConcurrentHashMap<>(); 
  15.         ipServerMap.putAll(ipMap); 
  16.         // 2.取出来key,放到set中 
  17.         Set<String> ipset=ipServerMap.keySet(); 
  18.         // 3.set放到list,要循环list取出 
  19.         ArrayList<String> iplist=new ArrayList<String>(); 
  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<String,Integer> 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<String,Integer> ipServerMap=new ConcurrentHashMap<>(); 
  14.         ipServerMap.putAll(ipMap); 
  15.         Set<String> ipSet=ipServerMap.keySet(); 
  16.         Iterator<String> ipIterator=ipSet.iterator(); 
  17.         //定义一个list放所有server 
  18.         ArrayList<String> ipArrayList=new ArrayList<String>(); 
  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<String,Integer> 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<String,Integer> ipServerMap=new ConcurrentHashMap<>(); 
  13.         ipServerMap.putAll(ipMap); 
  14.         Set<String> ipSet=ipServerMap.keySet(); 
  15.         //定义一个list放所有server 
  16.         ArrayList<String> ipArrayList=new ArrayList<String>(); 
  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<String,Integer> 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<String,Integer> ipServerMap=new ConcurrentHashMap<>(); 
  13.         ipServerMap.putAll(ipMap); 
  14.         Set<String> ipSet=ipServerMap.keySet(); 
  15.         Iterator<String> ipIterator=ipSet.iterator(); 
  16.         //定义一个list放所有server 
  17.         ArrayList<String> ipArrayList=new ArrayList<String>(); 
  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<weight;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<String,Integer> 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<String,Integer> ipServerMap=new ConcurrentHashMap<>(); 
  16.         ipServerMap.putAll(ipMap); 
  17.         //    2.取出来key,放到set中 
  18.         Set<String> ipset=ipServerMap.keySet(); 
  19.         //    3.set放到list,要循环list取出 
  20.         ArrayList<String> iplist=new ArrayList<String>(); 
  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开发编程
相关推荐

2021-10-10 13:31:14

Java负载均衡算法

2018-11-27 12:31:39

负载均衡高可用架构

2021-09-10 07:31:54

AndroidAppStartup原理

2020-01-14 09:40:00

Nginx负载均衡正向代理

2021-09-08 06:51:52

AndroidRetrofit原理

2021-10-15 09:19:17

AndroidSharedPrefe分析源码

2024-08-29 08:41:50

2021-09-17 06:55:50

AndroidLayoutView

2022-09-05 22:22:00

Stream操作对象

2021-09-24 08:10:40

Java 语言 Java 基础

2021-09-18 06:56:01

JavaCAS机制

2023-09-19 22:47:39

Java内存

2017-08-08 09:15:41

前端JavaScript页面渲染

2019-12-26 09:13:00

算法硬件软件

2021-02-17 11:25:33

前端JavaScriptthis

2022-01-14 12:28:18

架构OpenFeign远程

2020-08-10 18:03:54

Cache存储器CPU

2024-04-15 00:00:00

技术Attention架构

2022-11-04 09:43:05

Java线程

2024-03-12 00:00:00

Sora技术数据
点赞
收藏

51CTO技术栈公众号