Java 中怎么实现负载均衡算法

发布时间:2021-08-07 17:04:06 作者:Leah
来源:亿速云 阅读:176

Java 中怎么实现负载均衡算法,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

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、加权随机算法

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

在这里小编建了一个前端学习交流扣扣群:132667127,我自己整理的最新的前端资料和高级开发教程,如果有想需要的,可以加群一起学习交流

缺点:权重低的服务器可能很长一段时间都访问不到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 中怎么实现负载均衡算法的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

推荐阅读:
  1. java缓存核心技术的示例分析
  2. Java核心知识点整理

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:CSS中实现垂直居中的方法有哪些

下一篇:如何解决某些HTML字符打不出来的问题

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》