最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關于Java中常見的負載均衡算法

 更新時間:2023年08月15日 08:48:27   作者:Dreamlike223  
這篇文章主要介紹了關于Java中常見的負載均衡算法,負載平衡是一種電子計算機技術,用來在多個計算機、網絡連接、CPU、磁盤驅動器或其他資源中分配負載,以達到優(yōu)化資源使用、最大化吞吐率、最小化響應時間、同時避免過載的目的,需要的朋友可以參考下

負載均衡

在這里插入圖片描述

負載平衡(Load balancing)是一種電子計算機技術,用來在多個計算機(計算機集群)、網絡連接、CPU、磁盤驅動器或其他資源中分配負載,以達到優(yōu)化資源使用、最大化吞吐率、最小化響應時間、同時避免過載的目的。

使用帶有負載平衡的多個服務器組件,取代單一的組件,可以通過冗余提高可靠性。

負載平衡服務通常是由專用軟件和硬件來完成。

主要作用是將大量作業(yè)合理地分攤到多個操作單元上進行執(zhí)行,用于解決互聯(lián)網架構中的高并發(fā)和高可用的問題。

常見的負載均衡算法

在這里插入圖片描述

1.輪詢(Round Robin)

輪詢算法按照順序將新的請求分配給下一個服務器,最終實現平分請求。

實例:已知服務器: s1 ,s2, s3

請求1 -> s1

請求2-> s2

請求3 -> s3

請求4 -> s1

請求5 -> s2

請求6 -> s3

優(yōu)點:

  • ? 實現簡單,無需記錄各種服務的狀態(tài),是一種無狀態(tài)的負載均衡策略。
  • ? 實現絕對公平

缺點:

  • 當各個服務器性能不一致的情況,無法根據服務器性能去分配,無法合理利用服務器資源。

java實現輪詢算法:

思路:根據上面的介紹,依次的選擇下一個服務器,輪詢算法具有周期性的特性,這就是典型的周期性概念,我們第一想法應該就是取余了。

這里推薦大家《程序員的數學1》里面介紹了一些數學和編程思維的一些案例,其中就有介紹周期和分組的思想,個人感覺這本書還是不錯的,推薦給大家。

public class RoundRobin {
    @Data
    public static class Server {
        private int serverId;
        private String name;
        private int weight;
        public Server(int serverId, String name) {
            this.serverId = serverId;
            this.name = name;
        }
        public Server(int serverId, String name, int weight) {
            this.serverId = serverId;
            this.name = name;
            this.weight = weight;
        }
    }
    private static AtomicInteger NEXT_SERVER_COUNTER = new AtomicInteger(0);
    private static int select(int modulo) {
        for (; ; ) {
            int current = NEXT_SERVER_COUNTER.get();
            int next = (current + 1) % modulo;
            boolean compareAndSet = NEXT_SERVER_COUNTER.compareAndSet(current, next);
            if (compareAndSet) {
                return next;
            }
        }
    }
    public static Server selectServer(List<Server> serverList) {
        return serverList.get(select(serverList.size()));
    }
    public static void main(String[] args) {
        List<Server> serverList = new ArrayList<>();
        serverList.add(new Server(1, "服務器1"));
        serverList.add(new Server(2, "服務器2"));
        serverList.add(new Server(3, "服務器3"));
        for (int i = 0; i < 10; i++) {
            Server selectedServer = selectServer(serverList);
            System.out.format("第%d次請求,選擇服務器%s\n", i + 1, selectedServer.toString());
        }
    }
}

在這里插入圖片描述

2.加權輪詢(WeightedRound-Robin)

由于不同的服務器配置不同,因此它們處理請求的能力也不同,給配置高的機器配置相對較高的權重,讓其處理更多的請求,給配置較低的機器配置較低的權重減輕期負載壓力。

加權輪詢可以較好的解決這個問題。

思路:

根據權重的大小讓其獲得相應被輪詢到的機會。

已知:

服務器權重
s11
s22
s33

可以根據權重我們在內存中創(chuàng)建一個這樣的數組{s1,s2,s2,s3,s3,s3},然后再按照輪詢的方式選擇相應的服務器。

缺點:

  • 請求被分配到三臺服務器上機會不夠平滑。
  • 前3次請求都不會落在server3上。

Nginx實現了一種平滑的加權輪詢算法,可以將請求平滑(均勻)的分配到各個節(jié)點上。

下面我們用Java實現一下這個算法。

實現思路

我們以當前節(jié)點權重作為被選中的概率

 public void incrCurrentWeight() {
      this.currentWeight += weight;
 }

為了避免權重大的被連續(xù)選中,所以再被選中的時候我們應該讓其的當前權重變小。我們可以采用

//當前權重 = 當前權重 - 總權重

1-6 =-5

3-6 =-3

可得權重越大下次當前權重變成最大的可能性也越大

public void selected(int total) {
    this.currentWeight -= total;
}

我們選取當前當前權重最大的一個服務器

public class WeightRoundRobin {
    @Data
    public static class Server {
        private int serverId;
        private String name;
        private int weight;
        private int currentWeight;
        public Server(int serverId, String name) {
            this.serverId = serverId;
            this.name = name;
        }
        public Server(int serverId, String name, int weight) {
            this.serverId = serverId;
            this.name = name;
            this.weight = weight;
        }
        public void selected(int total) {
            this.currentWeight -= total;
        }
        public void incrCurrentWeight() {
            this.currentWeight += weight;
        }
    }
    public static Server selectServer(List<Server> serverList) {
        int total = 0;
        Server selectedServer = null;
        int maxWeight = 0;
        for (Server server : serverList) {
            total += server.getWeight();
            server.incrCurrentWeight();
          	//選取當前權重最大的一個服務器
            if (selectedServer == null || maxWeight < server.getCurrentWeight()) {
                selectedServer = server;
                maxWeight = server.getCurrentWeight();
            }
        }
        if (selectedServer == null){
            Random random = new Random();
            int next = random.nextInt(serverList.size());
            return serverList.get(next);
        }
        selectedServer.selected(total);
        return selectedServer;
    }
    public static void main(String[] args) {
        List<Server> serverList = new ArrayList<>();
        serverList.add(new Server(1, "服務器1", 1));
        serverList.add(new Server(2, "服務器2", 3));
        serverList.add(new Server(3, "服務器3", 10));
        for (int i = 0; i < 10; i++) {
            Server server = selectServer(serverList);
            System.out.format("第%d次請求,選擇服務器%s\n", i + 1, server.toString());
        }
    }

在這里插入圖片描述

3.隨機(Random)

思路:利用隨機數從所有服務器中隨機選取一臺,可以用服務器數組下標獲取。

public class RandomLoadBalance {
    @Data
    public static class Server {
        private int serverId;
        private String name;
        private int weight;
        public Server(int serverId, String name) {
            this.serverId = serverId;
            this.name = name;
        }
    }
    public static Server selectServer(List<Server> serverList) {
        Random selector = new Random();
        int next = selector.nextInt(serverList.size());
        return serverList.get(next);
    }
    public static void main(String[] args) {
        List<Server> serverList = new ArrayList<>();
        serverList.add(new Server(1, "服務器1"));
        serverList.add(new Server(2, "服務器2"));
        serverList.add(new Server(3, "服務器3"));
        for (int i = 0; i < 10; i++) {
            Server selectedServer = selectServer(serverList);
            System.out.format("第%d次請求,選擇服務器%s\n", i + 1, selectedServer.toString());
        }
    }
}

在這里插入圖片描述

4.加權隨機(Weight Random)

思路:

這里我們是利用區(qū)間的思想,通過一個小于在此區(qū)間范圍內的一個隨機數,選中對應的區(qū)間(服務器),區(qū)間越大被選中的概率就越大。

已知:

服務器權重
s11
s22
s33

那么: 

s1:[0,1]
s2:(1,3]
s3 (3,6]
public class WeightRandom {
    @Data
    public static class Server {
        private int serverId;
        private String name;
        private int weight;
        public Server(int serverId, String name) {
            this.serverId = serverId;
            this.name = name;
        }
        public Server(int serverId, String name, int weight) {
            this.serverId = serverId;
            this.name = name;
            this.weight = weight;
        }
    }
    private static Server selectServer(List<Server> serverList) {
        int sumWeight = 0;
        for (Server server : serverList) {
            sumWeight += server.getWeight();
        }
        Random serverSelector = new Random();
        int nextServerRange = serverSelector.nextInt(sumWeight);
        int sum = 0;
        Server selectedServer = null;
        for (Server server : serverList) {
            if (nextServerRange >= sum && nextServerRange < server.getWeight() + sum) {
                selectedServer = server;
            }
            sum += server.getWeight();
        }
        return selectedServer;
    }
    public static void main(String[] args) {
        List<Server> serverList = new ArrayList<>();
        serverList.add(new Server(1, "服務器1", 1));
        serverList.add(new Server(2, "服務器2", 5));
        serverList.add(new Server(3, "服務器3", 10));
        for (int i = 0; i < 10; i++) {
            Server selectedServer = selectServer(serverList);
            System.out.format("第%d次請求,選擇服務器%s\n", i + 1, selectedServer.toString());
        }
    }
}

在這里插入圖片描述

5.IPHash

思路:根據每個每個請求ip(也可以是某個標識)ip.hash() % server.size()

public class IpHash {
    @Data
    public static class Server {
        private int serverId;
        private String name;
        public Server(int serverId, String name) {
            this.serverId = serverId;
            this.name = name;
        }
    }
    public static Server selectServer(List<Server> serverList, String ip) {
        int ipHash = ip.hashCode();
        return serverList.get(ipHash % serverList.size());
    }
    public static void main(String[] args) {
        List<Server> serverList = new ArrayList<>();
        serverList.add(new Server(1, "服務器1"));
        serverList.add(new Server(2, "服務器2"));
        serverList.add(new Server(3, "服務器3"));
        List<String> ips = Arrays.asList("192.168.9.5", "192.168.9.2", "192.168.9.3");
        for (int i = 0; i < 10; i++) {
            for (String ip : ips) {
                Server selectedServer = selectServer(serverList, ip);
                System.out.format("請求ip:%s,選擇服務器%s\n", ip, selectedServer.toString());
            }
        }
    }
}

在這里插入圖片描述

可以看到結果:同一ip肯定會命中同一臺機器。

到此這篇關于關于Java中常見的負載均衡算法的文章就介紹到這了,更多相關Java負載均衡算法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot中將@Bean方法解析為BeanDefinition詳解

    SpringBoot中將@Bean方法解析為BeanDefinition詳解

    這篇文章主要介紹了SpringBoot中將@Bean方法解析為BeanDefinition詳解,得到的BeanDefinition是ConfigurationClassBeanDefinition類型,會為BeanDefinition設置factoryMethodName,這意味著當實例化這個bean的時候將采用工廠方法,需要的朋友可以參考下
    2023-12-12
  • SpringBoot+RabbitMQ+Redis實現商品秒殺的示例代碼

    SpringBoot+RabbitMQ+Redis實現商品秒殺的示例代碼

    本文主要介紹了SpringBoot+RabbitMQ+Redis實現商品秒殺,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • java實現ATM取款項目

    java實現ATM取款項目

    這篇文章主要為大家詳細介紹了java實現ATM取款項目的實現代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Java中實現Excel數字與文本轉換的示例代碼

    Java中實現Excel數字與文本轉換的示例代碼

    在數據處理過程中,經常會遇到需要將Excel單元格中的文本轉換為數字,或將數字轉換為文本的情況,下面就來詳細的介紹一下,感興趣的可以了解下
    2025-11-11
  • 程序猿必須要掌握的多線程安全問題之鎖策略詳解

    程序猿必須要掌握的多線程安全問題之鎖策略詳解

    在筆者面試過程時,經常會被問到各種各樣的鎖,如樂觀鎖、讀寫鎖等等,非常繁多,在此做一個總結,介紹的內容如下,需要的朋友可以參考下
    2021-06-06
  • ConstraintValidator類如何實現自定義注解校驗前端傳參

    ConstraintValidator類如何實現自定義注解校驗前端傳參

    這篇文章主要介紹了ConstraintValidator類實現自定義注解校驗前端傳參的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • SpringBoot v2.2以上重復讀取Request Body內容的解決方案

    SpringBoot v2.2以上重復讀取Request Body內容的解決方案

    這篇文章主要介紹了SpringBoot v2.2以上重復讀取Request Body內容的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring之ShutDown?Hook死鎖現象解讀

    Spring之ShutDown?Hook死鎖現象解讀

    這篇文章主要介紹了Spring之ShutDown?Hook死鎖現象解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 淺談spring security入門

    淺談spring security入門

    這篇文章主要介紹了淺談spring security入門,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • Java 自旋鎖(spinlock)相關知識總結

    Java 自旋鎖(spinlock)相關知識總結

    這篇文章主要介紹了Java 自旋鎖(spinlock)相關知識總結,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-02-02

最新評論

仙桃市| 盈江县| 泰和县| 乾安县| 南昌市| 陇南市| 衡阳县| 同江市| 大城县| 山东| 丽水市| 云梦县| 吉安市| 应城市| 洮南市| 张掖市| 沈丘县| 台安县| 克拉玛依市| 厦门市| 黑龙江省| 霍林郭勒市| 望奎县| 搜索| 利川市| 时尚| 南部县| 金山区| 防城港市| 天等县| 二连浩特市| 三穗县| 凤台县| 揭西县| 子长县| 应城市| 太白县| 新丰县| 腾冲县| 雷州市| 青川县|