首页 > 编程语言 >Java实现5种负载均衡算法

Java实现5种负载均衡算法

时间:2022-11-16 13:03:46浏览次数:62  
标签:负载 Java List 算法 DbConfig import new data public

Java实现5种负载均衡算法

1. 轮询算法
import com.google.common.collect.Lists;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 轮询算法
 * 轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器。
 * 优点:绝对公平
 * 缺点:无法根据服务器性能去分配,无法合理利用服务器资源。
 * @author: 
 * @date: 2022-11-10 17:53
 */
public class Round<T> {

    private AtomicInteger index = new AtomicInteger(0);

    public <T> T roundRobin(List<T> data) {
        T t ;
        if (index.get() >= data.size()) {
           index = new AtomicInteger(0);
        }
        t = data.get(index.get());
         //轮询+1
        index.getAndIncrement();
        return t;
    }

    public static void main(String[] args) {
        List<String> ips = Lists.newArrayList("192.168.1.1", "192.168.1.2", "192.168.1.3");
        Round<String> testRoundRobin =new Round<String>();
        for (int i=0;i< 10 ;i++){
            String s = testRoundRobin.roundRobin(ips);
            System.out.println(s);
        }
    }
}
2. 加权轮询法
import com.collmall.shortlink.entity.DbConfig;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 加权轮询法
 * 该算法中,每个机器接受的连接数量是按权重比例分配的。这是对普通轮询算法的改进,
 * 比如你可以设定:第三台机器的处理能力是第一台机器的两倍,那么负载均衡器会把两倍的连接数量分配给第3台机器,轮询可以将请求顺序按照权重分配到后端。
 * @author 
 * @date 2022年11月11日14:46:25
 */
public class Weight<T> {

    private AtomicInteger index = new AtomicInteger(0);


    public List<T> getDataByWeight(List<T> data) throws NoSuchFieldException, IllegalAccessException {
        List<T> ips = new CopyOnWriteArrayList<T>();
        if (CollectionUtils.isEmpty(data)) {
            return data;
        }
        for (T t : data) {
            Field nameField = t.getClass().getDeclaredField("name");
            // setAccessible 实体中的属性是用private定义的,需要设置setAccessible 为true,才可以访问到对象
            nameField.setAccessible(true);
            // 获取属性值
            String name  =(String) nameField.get(t);

            Field weightField = t.getClass().getDeclaredField("weight");
            // setAccessible 实体中的属性是用private定义的,需要设置setAccessible 为true,才可以访问到对象
            weightField.setAccessible(true);
            // 获取属性值
            Integer weight = (Integer) weightField.get(t);

            for (int ipCount =0; ipCount < weight; ipCount++) {
                ips.add(t);
            }
        }
        return ips;
    }
  
    public  T weightRobin(List<T> data) throws NoSuchFieldException, IllegalAccessException {
        List<T> list = this.getDataByWeight(data);
        if (index.get() >= list.size()){
            index = new AtomicInteger(0);
        }
        T t = list.get(index.get());
        index.getAndIncrement();
        return  t;
    }
  
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Weight testWeightRobin=new Weight();
        List<DbConfig> dbConfigList= new ArrayList<>();
        dbConfigList.add(new DbConfig("192.168.1.1", 1));
        dbConfigList.add(new DbConfig("192.168.1.2", 2));
        dbConfigList.add(new DbConfig("192.168.1.3", 4));
        for (int i =0;i< 10 ;i++){
            DbConfig server = (DbConfig)testWeightRobin.weightRobin(dbConfigList);
            System.out.println(server);
        }
    }
}
3. 加权随机法
import com.collmall.shortlink.entity.DbConfig;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 加权随机法
 * 获取带有权重的随机数字,随机这种东西,不能看绝对,只能看相对,
 * 我们不用index 控制下标进行轮询,只用random 进行随机取ip,即实现算法。
 * @author 
 * @date 2022年11月14日11:37:20
 */
public class RandomWeight<T> {
 
    public <T> List<T> getDataByWeight(List<T> data) throws NoSuchFieldException, IllegalAccessException {
        List<T> ips = new CopyOnWriteArrayList<T>();
        for (T t : data) {
            Field nameField = t.getClass().getDeclaredField("name");
            // setAccessible 实体中的属性是用private定义的,需要设置setAccessible 为true,才可以访问到对象
            nameField.setAccessible(true);
            // 获取属性值
            String name  =(String) nameField.get(t);

            Field weightField = t.getClass().getDeclaredField("weight");
            // setAccessible 实体中的属性是用private定义的,需要设置setAccessible 为true,才可以访问到对象
            weightField.setAccessible(true);
            // 获取属性值
            Integer weight = (Integer) weightField.get(t);
            // 根据权重不同,放入list 中的数量等同于权重,轮询出的的次数等同于权重
            for (int ipCount =0; ipCount < weight; ipCount++) {
                ips.add(t);
            }
        }

        return ips;
    }
 
    public <T> T randomWeightRobin(List<T> data) throws NoSuchFieldException, IllegalAccessException {
        List<T> ips = this.getDataByWeight(data);
//        //循环随机数
//        Random random=new Random();
//        int index =random.nextInt();
        int index = ThreadLocalRandom.current().nextInt(ips.size());
        T t = ips.get(index);
        return  t;
    }

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        RandomWeight<DbConfig> randomWeightRobin =new RandomWeight<DbConfig>();
        List<DbConfig> dbConfigList= new ArrayList<>();
        dbConfigList.add(new DbConfig("192.168.1.1", 1));
        dbConfigList.add(new DbConfig("192.168.1.2", 2));
        dbConfigList.add(new DbConfig("192.168.1.3", 4));
        for (int i =0;i< 10 ;i++){
            DbConfig server = randomWeightRobin.randomWeightRobin(dbConfigList);
            System.out.println(server);
        }

    }
}
4. 随机法
import com.collmall.shortlink.entity.DbConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 随机法
 * 负载均衡方法随机的把负载分配到各个可用的服务器上,通过随机数生成算法选取一个服务器,
 * 这种实现算法最简单,随之调用次数增大,这种算法可以达到每台服务器的请求量接近于平均。
 * @author 
 * @date  2022年11月14日13:46:24
 */
public class Random<T> {


    public <T> T randomRobin(List<T> data){
        int index = ThreadLocalRandom.current().nextInt(data.size());
        T t = data.get(index);
        return  t;
 
    }
 
    public static void main(String[] args) {
        Random<DbConfig> randomdRobin =new Random<DbConfig>();
        List<DbConfig> dbConfigList= new ArrayList<>();
        dbConfigList.add(new DbConfig("192.168.1.1", 1));
        dbConfigList.add(new DbConfig("192.168.1.2", 2));
        dbConfigList.add(new DbConfig("192.168.1.3", 4));
        for (int i=0;i< 10 ;i++){
            DbConfig dbConfig = randomdRobin.randomRobin(dbConfigList);
            System.out.println(dbConfig);
        }
    }
}
5. IP_Hash 法
import com.collmall.shortlink.entity.DbConfig;

import java.util.ArrayList;
import java.util.List;

/**
 * IP_Hash算法
 * hash(ip)%N算法,通过一种散列算法把客户端来源IP根据散列取模算法将请求分配到不同的服务器上
 *
 * 优点:保证了相同客户端IP地址将会被哈希到同一台后端服务器,直到后端服务器列表变更。根据此特性可以在服务消费者与服务提供者之间建立有状态的session会话
 *
 * 缺点: 如果服务器进行了下线操作,源IP路由的服务器IP就会变成另外一台,如果服务器没有做session 共享话,会造成session丢失。
 * @author 
 * @date 2022年11月14日14:06:41
 */
public class IpHash<T> {


    /**
     *
     * @param data
     * @param hashData
     * @param <T>
     * @return
     */
    public <T> T ipHashRobin(List<T> data,String hashData) {
//        int hashCode = hashData.hashCode();
//        int listSize = data.size();
//        int index = hashCode % listSize;
        int index = hashData.hashCode() % data.size();
        T t = data.get(index);
        return  t;
 
    }
 
    public static void main(String[] args) {
        IpHash<DbConfig> ipHash =new IpHash<DbConfig>();
        List<DbConfig> dbConfigList= new ArrayList<>();
        dbConfigList.add(new DbConfig("192.168.1.1", 1));
        dbConfigList.add(new DbConfig("192.168.1.2", 2));
        dbConfigList.add(new DbConfig("192.168.1.3", 4));
        DbConfig dbConfig = ipHash.ipHashRobin(dbConfigList, "192.168.88.2");
        System.out.println(dbConfig.toString());
    }
}
6. 附录 DbConfig
public class DbConfig  {
    //id
    private Long id;
    //数据库名称
    private String name;
    //负载策略:1轮询算法 ,2 加权轮询法,3 加权随机法,4 随机法,5 IP_Hash算法
    private Integer loadPolicy;
    //权重: 只有 2 加权轮询法,3 加权随机法 才会用到
    private Integer weight;
    //是否删除:0 未删除,1是已删除
    private Integer isDeleted;
    //创建时间
    private Date cT;
    //更新时间
    private Date uT;


    public DbConfig(String name, Integer weight) {
        this.name = name;
        this.weight = weight;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getLoadPolicy() {
        return loadPolicy;
    }

    public void setLoadPolicy(Integer loadPolicy) {
        this.loadPolicy = loadPolicy;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public Integer getIsDeleted() {
        return isDeleted;
    }

    public void setIsDeleted(Integer isDeleted) {
        this.isDeleted = isDeleted;
    }

    public Date getCT() {
        return cT;
    }

    public void setCT(Date cT) {
        this.cT = cT;
    }

    public Date getUT() {
        return uT;
    }

    public void setUT(Date uT) {
        this.uT = uT;
    }

    /**
     * 获取主键值
     *
     * @return 主键值
     */
    @Override
    protected Serializable pkVal() {
        return this.id;
    }

    @Override
    public String toString() {
        return "DbConfig{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", loadPolicy=" + loadPolicy +
                ", weight=" + weight +
                ", isDeleted=" + isDeleted +
                ", cT=" + cT +
                ", uT=" + uT +
                '}';
    }
}

参考:

Java实现5种负载均衡算法(小结)_java_脚本之家 (jb51.net)

标签:负载,Java,List,算法,DbConfig,import,new,data,public
From: https://blog.51cto.com/u_4981212/5855862

相关文章

  • JAVA随机数的产生
     产生随机数的类和方法Randomrandom=newRandom();//Random(longseed):使用单个long类型的参数创建一个新的随机数生成器。random.nextBoolean();random.nextDoub......
  • 力扣374(java&python)-猜数字大小(简单)
    题目:猜数字游戏的规则如下:每轮游戏,我都会从 1 到 n随机选择一个数字。请你猜选出的是哪个数字。如果你猜错了,我会告诉你,你猜测的数字比我选出的数字是大了还是小了......
  • 【Java】zuul
    报错com.netflix.zuul.exception.ZuulException:HystrixReadedtimeout解决办法,zuul模块的yml配置文件增加ribbon:ConnectTimeout:5000#连接超时时间(ms)......
  • Java SpringBoot FTP 上传下载文件
    POM添加依赖<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.7</version></dependency><!--......
  • QT客户端与Java服务端进行https通信_F_hawk189_新浪博客
    网上也有一部分教程,不过我还是踩了许多的坑,所以整理了一下网上看到的和自己的一些收获。首先:,Tomcat.truststore(包含信任库),首先说明一下这个两个文件   cl......
  • LCA 之 Tarjan(离线)算法
    \(LCA\)之\(Tarjan\)(离线)算法什么是最近公共祖先?在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先......
  • 网易严选搜索推荐实践之:“全能选手”召回表征算法实践.pdf(附下载链接)...
    今天给大家带来网易严选人工智能部算法专家潘胜一先生所做的分享《网易严选搜索推荐实践之:“全能选手”召回表征算法实践.pdf》。潘先生所在的团队主要负责搜索推荐,搜索推荐......
  • 7.jenkins调用maven工具管理java代码实现滚动发布
    1.配置多jdk环境2.配置多maven环境3.配置maven项目3.1配置部署主机[root@jenkinswar_update]#cathosts_test[webservice]192.168.1.191[root@jenkinswar_......
  • Java-10接口与抽象类
    Java-10接口与抽象类抽象方法abstractmethod机制这是一个不完整的方法,它只有一个声明,没有方法体abstractvoidf();包含抽象方法的类被称为抽象类:如果一个类包含一......
  • 如何理解Java中眼花缭乱的各种并发锁?
    在互联网公司面试中,很多小伙伴都被问到过关于锁的问题。今天,我给大家一次性把Java并发锁的全家桶彻底讲明白。包括互斥锁、读写锁、重入锁、公平锁、悲观锁、自旋锁、偏向......