您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

Java 实现6种负载均衡算法

时间:2020-03-04 19:06:05  来源:  作者:

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 + "访问"));
        }
    }
 
}


Tags:负载均衡   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
负载均衡是将客户端请求访问,通过提前约定好的规则转发给各个server。其中有好几个种经典的算法,下面我们用Java实现这几种算法。 轮询算法轮询算法按顺序把每个新的连接请求...【详细内容】
2021-09-27  Tags: 负载均衡  点击:(52)  评论:(0)  加入收藏
什么是NginxNginx(engine x)是一个高性能的HTTP和反向代理服务器,具有内存少,高并发特点强。1、处理静态文件,索引文件以及自动检索打开文件描述符缓冲2、无缓冲的反向代理加速...【详细内容】
2021-09-02  Tags: 负载均衡  点击:(70)  评论:(0)  加入收藏
1.安装依赖环境yum -y install wget gcc-c++ ncurses ncurses-devel cmake make perl bison openssl openssl-devel gcc* libxml2 libxml2-devel curl-devel libjpeg* libpn...【详细内容】
2021-08-03  Tags: 负载均衡  点击:(63)  评论:(0)  加入收藏
域名解析是客户端访问系统的第一步。在架构设计中,DNS Server除了解析域名,还能干点什么呢?又有哪些“挖坑”的用法需要避免呢?典型的互联网架构中,我们通过nginx的反向代理来做...【详细内容】
2021-07-29  Tags: 负载均衡  点击:(264)  评论:(0)  加入收藏
均衡算法也是多种多样,常见的两大类:即静态负载均衡法和动态负载均衡法。静态算法也是比较简单,主要有有一般轮询算法,基于比例的加权轮询算法,以及基于优先级的轮询算法。动态算...【详细内容】
2021-07-27  Tags: 负载均衡  点击:(72)  评论:(0)  加入收藏
今天总结一下负载均衡中LVS与Nginx的区别,好几篇博文一开始就说LVS是单向的,Nginx是双向的,我个人认为这是不准确的,LVS三种模式中,虽然DR模式以及TUN模式只有请求的报文经过Director,但是NAT模式,Real Server回复的...【详细内容】
2021-06-08  Tags: 负载均衡  点击:(114)  评论:(0)  加入收藏
之前有很多朋友问关于 Nginx 的 upstream 模块中 max_fails 及 fail_timeout,这两个指令,分别是配置关于负载均衡过程中,对于上游(后端)服务器的失败尝试次数和不可用时间,很多...【详细内容】
2021-04-15  Tags: 负载均衡  点击:(206)  评论:(0)  加入收藏
需求在Linux SMP(对称多处理器)环境下,每个CPU对应一个run_queue(可执行队列)。如果一个进程处于TASK_RUNNING状态(可执行状态),则它会被加入到其中一个run_queue(且同一时刻仅会被加...【详细内容】
2021-04-01  Tags: 负载均衡  点击:(225)  评论:(0)  加入收藏
分层模型,每一层实现各自的功能和协议,并完成与相邻层的接口通讯。OSI 的服务定义详细说明了各层所提供的服务,某一层的服务就是该层及其下各层的一种能力,通过接口提供给更高一层。各层所提供的服务与这些服务是怎么实现...【详细内容】
2021-03-16  Tags: 负载均衡  点击:(257)  评论:(0)  加入收藏
Nginx的安装及负载均衡配置在安装完分布式文件系统之后,就可以在应用程序中进行调用了。注意需要在 Web端的页面上进行访问,还必须借助Nginx 提供访问服务。使用Nginx 不仅可...【详细内容】
2021-03-11  Tags: 负载均衡  点击:(159)  评论:(0)  加入收藏
▌简易百科推荐
前言Kafka 中有很多延时操作,比如对于耗时的网络请求(比如 Produce 是等待 ISR 副本复制成功)会被封装成 DelayOperation 进行延迟处理操作,防止阻塞 Kafka请求处理线程。Kafka...【详细内容】
2021-12-27  Java技术那些事    Tags:时间轮   点击:(1)  评论:(0)  加入收藏
博雯 发自 凹非寺量子位 报道 | 公众号 QbitAI在炼丹过程中,为了减少训练所需资源,MLer有时会将大型复杂的大模型“蒸馏”为较小的模型,同时还要保证与压缩前相当的结果。这就...【详细内容】
2021-12-24  量子位    Tags:蒸馏法   点击:(11)  评论:(0)  加入收藏
分稀疏重建和稠密重建两类:稀疏重建:使用RGB相机SLAMOrb-slam,Orb-slam2,orb-slam3:工程地址在: http://webdiis.unizar.es/~raulmur/orbslam/ DSO(Direct Sparse Odometry)因为...【详细内容】
2021-12-23  老师明明可以靠颜值    Tags:算法   点击:(7)  评论:(0)  加入收藏
1. 基本概念希尔排序又叫递减增量排序算法,它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的;希尔排序是一种不稳定的排序算法...【详细内容】
2021-12-22  青石野草    Tags:希尔排序   点击:(6)  评论:(0)  加入收藏
ROP是一种技巧,我们对execve函数进行拼凑来进行system /bin/sh。栈迁移的特征是溢出0x10个字符,在本次getshell中,还碰到了如何利用printf函数来进行canary的泄露。ROP+栈迁移...【详细内容】
2021-12-15  星云博创    Tags:栈迁移   点击:(22)  评论:(0)  加入收藏
一、什么是冒泡排序1.1、文字描述冒泡排序是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地...【详细内容】
2021-12-15    晓掌柜丶韶华  Tags:排序算法   点击:(16)  评论:(0)  加入收藏
在了解golang的map之前,我们需要了解哈希这个概念。哈希表,又称散列表(Hash table),是根据键(key)而直接访问在内存储存位置的数据结构。也就是说,它通过计算出一个键值的函数,将...【详细内容】
2021-12-07  一棵梧桐木    Tags:哈希表   点击:(14)  评论:(0)  加入收藏
前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯&middot;奈特称,一般的雪花大约由10^19个水分子...【详细内容】
2021-11-17  小心程序猿QAQ    Tags:雪花算法   点击:(24)  评论:(0)  加入收藏
导读:在大数据时代,对复杂数据结构中的各数据项进行有效的排序和查找的能力非常重要,因为很多现代算法都需要用到它。在为数据恰当选择排序和查找策略时,需要根据数据的规模和类型进行判断。尽管不同策略最终得到的结果完...【详细内容】
2021-11-04  华章科技    Tags:排序算法   点击:(40)  评论:(0)  加入收藏
这是我在网上找的资源的一个总结,会先给出一个我看了觉得还行的关于算法的讲解,再配上实现的代码: Original author: Bill_Hoo Original Address: http://blog.sina.com.cn/s/bl...【详细内容】
2021-11-04  有AI野心的电工和码农    Tags: KMP算法   点击:(36)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条