溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java 中怎么實現(xiàn)負載均衡算法

發(fā)布時間:2021-08-07 17:04:06 來源:億速云 閱讀:167 作者:Leah 欄目:web開發(fā)

Java 中怎么實現(xiàn)負載均衡算法,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

1、完全隨機算法

缺點:所有服務(wù)器的訪問概率都是相同的。

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、加權(quán)隨機算法

場景:有的服務(wù)器性能高,可以讓隨機到此服務(wù)器的可能性增大

在這里小編建了一個前端學(xué)習(xí)交流扣扣群:132667127,我自己整理的最新的前端資料和高級開發(fā)教程,如果有想需要的,可以加群一起學(xué)習(xí)交流

缺點:權(quán)重低的服務(wù)器可能很長一段時間都訪問不到3

package com.example.demo.core.random;

import java.util.*;

/**
* 負載均衡算法
*
* 如果某一臺服務(wù)器性能比較高,設(shè)置訪問的權(quán)重高一點
*
* 加權(quán)隨機算法
*/
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();

   /**
    * 當(dāng)權(quán)重設(shè)置過大時,list容易被撐爆
    * @return
    */
   public static String getServer() {

       List<String> list = new ArrayList<>();

       for(Map.Entry<String,Integer> entry: map.entrySet()) {

           //根據(jù)權(quán)重,決定向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);
   }


   /**
    * 優(yōu)化后
    * @return
    */
   public static String getServer1() {
       //計算總權(quán)值
       int weight = map.values().stream().mapToInt(p -> p).sum();

       //隨機一個隨機數(shù)
       int index = random.nextInt(weight);

       //遍歷  服務(wù)  map
       for(Map.Entry<String,Integer> entry : map.entrySet()) {
           //如果權(quán)重大于  索引
           if(entry.getValue() >= index) {
               // 返回這個服務(wù)
               return entry.getKey();
           }
           //否則,索引 = 當(dāng)前索引 - 當(dāng)前服務(wù)的權(quán)重
           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、完全輪詢算法

缺點:從頭到尾輪詢一遍,不能根據(jù)服務(wù)器性能設(shè)置權(quán)重

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、加權(quán)輪詢算法

有點:可以根據(jù)服務(wù)器性能設(shè)置訪問權(quán)重

缺點:可能某個服務(wù)器權(quán)重大,長時間執(zhí)行,遇到耗時大的請求,壓力會很大

package com.example.demo.core.poll;

import java.util.HashMap;
import java.util.Map;

/**
* 加權(quán)輪詢算法
* 實際中可能遇到某個服務(wù)器壓力較大,長時間執(zhí)行。
*/
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、平滑加權(quán)輪詢算法

優(yōu)點:根據(jù)權(quán)重分配服務(wù),同時又保證權(quán)重低的服務(wù)可以被訪問到

缺點:集群環(huán)境下,同一個用戶訪問無法分流到固定一臺機器

package com.example.demo.core.smooth;

/**
* 平滑加權(quán)
*/
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;

/**
* 平滑加權(quán)輪詢算法
*/
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負載算法
* 在一個集群環(huán)境下,讓同一個用戶的訪問,分流到固定的一臺機器上
*/
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 + "訪問"));
       }
   }

}

看完上述內(nèi)容,你們掌握Java 中怎么實現(xiàn)負載均衡算法的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI