1. 首页
  2. >
  3. 编程技术
  4. >
  5. Java

Java 实现6种负载均衡算法

1、完全随机算法

缺点:所有服务器的访问概率都是相同的。

package com.example.demo.core.random;   import java.util.Arrays; import java.util.List; import java.util.Random;   /**  * 负载均衡算法  * 完全随机算法  */ public class RandomServer {       public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");       static Random random = new Random();       public static String getServer() {         int number = random.nextInt(list.size());         return list.get(number);     }       public static void main(String[] args) {         for(int i = 0; i < 15; i++) {             System.out.println(getServer());         }     } }

2、加权随机算法

场景:有的服务器性能高,可以让随机到此服务器的可能性增大

缺点:权重低的服务器可能很长一段时间都访问不到3

package com.example.demo.core.random;   import java.util.*;   /**  * 负载均衡算法  *  * 如果某一台服务器性能比较高,设置访问的权重高一点  *  * 加权随机算法  */ public class WeightRandomServer {       public static Map<String,Integer> map = new HashMap<>();       static {         map.put("10.180.11.126:8888",2);         map.put("10.180.11.128:8888",7);         map.put("10.180.11.130:8888",1);     }       static Random random = new Random();       /**      * 当权重设置过大时,list容易被撑爆      * @return      */     public static String getServer() {           List<String> list = new ArrayList<>();           for(Map.Entry<String,Integer> entry: map.entrySet()) {               //根据权重,决定向list中添加几次             for(int i = 0; i < entry.getValue(); i++) {                   list.add(entry.getKey());             }         }         //list的大小         int weight = map.values().stream().mapToInt(p -> p).sum();           int number = random.nextInt(weight);           return list.get(number);     }         /**      * 优化后      * @return      */     public static String getServer1() {         //计算总权值         int weight = map.values().stream().mapToInt(p -> p).sum();           //随机一个随机数         int index = random.nextInt(weight);           //遍历  服务  map         for(Map.Entry<String,Integer> entry : map.entrySet()) {             //如果权重大于  索引             if(entry.getValue() >= index) {                 // 返回这个服务                 return entry.getKey();             }             //否则,索引 = 当前索引 - 当前服务的权重             index = index - entry.getValue();         }         return "";     }       public static void main(String[] args) {           for(int i = 0; i < 15; i++) {               //System.out.println(getServer());             System.out.println(getServer1());         }     } }

3、完全轮询算法

缺点:从头到尾轮询一遍,不能根据服务器性能设置权重

package com.example.demo.core.poll;   import java.util.Arrays; import java.util.List;   /**  * 完全轮询算法  */ public class PollServer {     public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");       static int index;       public static String getServer() {         if(index == list.size()) {             index = 0;         }         return list.get(index++);     }       public static void main(String[] args) {           for(int i = 0; i < 15; i++) {               System.out.println(getServer());         }     } }

4、加权轮询算法

有点:可以根据服务器性能设置访问权重

缺点:可能某个服务器权重大,长时间执行,遇到耗时大的请求,压力会很大

package com.example.demo.core.poll;   import java.util.HashMap; import java.util.Map;   /**  * 加权轮询算法  * 实际中可能遇到某个服务器压力较大,长时间执行。  */ public class WeightPollServer {       public static Map<String,Integer> map = new HashMap<>();       static {         map.put("10.180.11.126:8888",2);         map.put("10.180.11.128:8888",7);         map.put("10.180.11.130:8888",5);     }       static int index;       public static String getServer() {         int weight = map.values().stream().mapToInt( p -> p).sum();         int number = (index++) % weight;         for(Map.Entry<String,Integer> entry : map.entrySet()) {             if(entry.getValue() >= number) {                 return entry.getKey();             }             number = number - entry.getValue();         }         return "";     }       public static void main(String[] args) {           for(int i = 0; i < 15; i++) {             System.out.println(getServer());         }     } }

5、平滑加权轮询算法

优点:根据权重分配服务,同时又保证权重低的服务可以被访问到

缺点:集群环境下,同一个用户访问无法分流到固定一台机器

package com.example.demo.core.smooth;   /**  * 平滑加权  */ public class SmoothWeight {       private int weight;       private int currentWeight;       private String address;         public int getWeight() {         return weight;     }       public void setWeight(int weight) {         this.weight = weight;     }       public int getCurrentWeight() {         return currentWeight;     }       public void setCurrentWeight(int currentWeight) {         this.currentWeight = currentWeight;     }       public String getAddress() {         return address;     }       public void setAddress(String address) {         this.address = address;     }       public SmoothWeight(int weight, int currentWeight, String address) {         this.weight = weight;         this.currentWeight = currentWeight;         this.address = address;     } }
package com.example.demo.core.smooth;   import java.util.HashMap; import java.util.Map;   /**  * 平滑加权轮询算法  */ public class SmoothWeightPollServer {         public static Map<String,SmoothWeight> map = new HashMap<>();       static {         map.put("10.180.11.126:8888",new SmoothWeight(5,5,"10.180.11.126:8888"));         map.put("10.180.11.128:8888",new SmoothWeight(2,2,"10.180.11.128:8888"));         map.put("10.180.11.130:8888",new SmoothWeight(4,4,"10.180.11.130:8888"));     }       public static String getServer() {           SmoothWeight maxSmoothWeight = null;           int weight = map.values().stream().mapToInt(SmoothWeight :: getWeight).sum();           for(Map.Entry<String,SmoothWeight> entry : map.entrySet()) {               SmoothWeight currentSmoothWeight = entry.getValue();               if(maxSmoothWeight == null || currentSmoothWeight.getCurrentWeight() > maxSmoothWeight.getCurrentWeight()) {                 maxSmoothWeight = currentSmoothWeight;             }         }         assert maxSmoothWeight != null;         maxSmoothWeight.setCurrentWeight(maxSmoothWeight.getCurrentWeight() - weight);         for(Map.Entry<String,SmoothWeight> entry : map.entrySet()) {               SmoothWeight currentSmoothWeight = entry.getValue();               currentSmoothWeight.setCurrentWeight(currentSmoothWeight.getCurrentWeight() + currentSmoothWeight.getWeight());         }           return maxSmoothWeight.getAddress();     }         public static void main(String[] args) {           for(int i = 0; i < 15; i++) {             System.out.println(getServer());         }     } }

6、哈希负载算法

package com.example.demo.core.hash;   import java.util.Arrays; import java.util.List; import java.util.SortedMap; import java.util.TreeMap;   /**  * hash负载算法  * 在一个集群环境下,让同一个用户的访问,分流到固定的一台机器上  */ public class HashServer {       public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");       public static String getServer(String client){         int nodeCount = 40;           TreeMap<Integer,String> treeMap = new TreeMap<>();           for(String s : list) {             for(int i = 0; i < nodeCount; i++) {                 treeMap.put((s + "address:" + i).hashCode(), s);             }         }           SortedMap<Integer,String> sortedMap = treeMap.tailMap(client.hashCode());           Integer firstHash = (sortedMap.size() > 0) ? sortedMap.firstKey() : treeMap.firstKey();           return treeMap.get(firstHash);     }       public static void main(String[] args) {           for(int i = 0; i < 100; i++) {             System.out.println(getServer("用户:" + i + "访问"));         }     }   }


Java 实现6种负载均衡算法

祝您学习愉快