Java负载均衡的实现原理

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: Java负载均衡的实现原理介绍及代码

1、负载均衡算法简介和实现

1.1、随机

通过随机算法,根据后端服务器的列表随机选取其中的一台服务器进行访问

@Component
public class RandomStrategy implements LoadBalanceStrategy {

    @Override
    public String load(List<String> uris) {
        // 0~bound(不包含)之间的随机数
        int randomNumber = new Random().nextInt(uris.size());
        return uris.get(randomNumber);
    }
}

1.2、轮询

将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载;

@Component
public class RoundRobinStrategy implements LoadBalanceStrategy {

    /**
     * 定义原子计数类
     */
    private AtomicInteger index = new AtomicInteger(0);

    @Override
    public String load(List<String> uris) {
        return uris.get(Math.abs(index.incrementAndGet() % uris.size()));
    }
}

1.3、加权随机

加权随机法根据后端机器的配置,系统的负载分配不同的权重。随机获取服务器进行转发请求,本质上就是按照权重往列表多放了数据,但是还是随机的。

@Component
public class RandomWeightStrategy implements LoadBalanceStrategy {

    @Override
    public String load(List<String> uris) {
        // 0~bound(不包含)之间的随机数
        int randomNumber = new Random().nextInt(uris.size());
        return uris.get(randomNumber);
    }


    public String load(List<String> uris,List<Integer> weights) {
        // 构建加权list
        List<String> weightUris = new ArrayList<>();
        if(uris.size() != weights.size()){
            throw new RuntimeException("转发服务器列表需和权重列表数量一致");
        }

        for (int i = 0; i < uris.size(); i++) {
            Integer weight = weights.get(i);
            if(weight<=0){
                continue;
            }
            for (int j = 0; j < weight; j++) {
                weightUris.add(uris.get(i));
            }
        }

        // 0~bound(不包含)之间的随机数
        int randomNumber = new Random().nextInt(weightUris.size());
        return uris.get(randomNumber);
    }
}

1.4、加权轮询

同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端;

public class RoundRobinWeightStrategy implements LoadBalanceStrategy{

    /**
     * 定义原子计数类
     */
    private AtomicInteger index = new AtomicInteger(0);

    @Override
    public String load(List<String> uris) {
        return uris.get(Math.abs(index.incrementAndGet() % uris.size()));
    }


    public String load(List<String> uris,List<Integer> weights) {
        // 构建加权list
        List<String> weightUris = new ArrayList<>();
        if(uris.size() != weights.size()){
            throw new RuntimeException("转发服务器列表需和权重列表数量一致");
        }

        for (int i = 0; i < uris.size(); i++) {
            Integer weight = weights.get(i);
            if(weight<=0){
                continue;
            }
            for (int j = 0; j < weight; j++) {
                weightUris.add(uris.get(i));
            }
        }

        return uris.get(Math.abs(index.incrementAndGet() % uris.size()));
    }

}

1.5、IpHash

通过请求ip进行hash,可以让服务器列表处理请求更加均衡

@Component
public class IpHashStrategy implements LoadBalanceStrategy {

    @Override
    public String load(List<String> uris) {
        return null;
    }

    public String load(List<String> uris, String ip) {
        return uris.get(ip.hashCode() % uris.size());
    }
}
相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
2月前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
2月前
|
存储 算法 Java
【Java集合类面试八】、 介绍一下HashMap底层的实现原理
HashMap基于hash算法,通过put和get方法存储和获取对象,自动调整容量,并在碰撞时用链表或红黑树组织元素以优化性能。
|
1月前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
13天前
|
负载均衡 算法 Java
java中nginx负载均衡配置
java中nginx负载均衡配置
30 0
|
2月前
|
安全 Java UED
Java线程池的实现原理及其在业务中的最佳实践
本文讲述了Java线程池的实现原理和源码分析以及线程池在业务中的最佳实践。
|
2月前
|
存储 安全 Java
解锁Java并发编程奥秘:深入剖析Synchronized关键字的同步机制与实现原理,让多线程安全如磐石般稳固!
【8月更文挑战第4天】Java并发编程中,Synchronized关键字是确保多线程环境下数据一致性与线程安全的基础机制。它可通过修饰实例方法、静态方法或代码块来控制对共享资源的独占访问。Synchronized基于Java对象头中的监视器锁实现,通过MonitorEnter/MonitorExit指令管理锁的获取与释放。示例展示了如何使用Synchronized修饰方法以实现线程间的同步,避免数据竞争。掌握其原理对编写高效安全的多线程程序极为关键。
58 1
|
3月前
|
Java 开发者
Java实现基于清除后分配规则的垃圾回收器及其实现原理
通过上述简化模型的实现,我们可以理解基于清除后分配规则的垃圾回收器的基本工作原理。实际上,现代JVM中的垃圾回收器比这个例子复杂得多,它们可能包括更多阶段、优化策略,以及不同类型的垃圾回收器协同工作。然而,理解这一基本概念对于深入理解垃圾回收机制和内存管理非常有帮助。
22 3
|
4月前
|
存储 算法 Java
滚雪球学Java(65):深入理解Java中的Map接口:实现原理剖析
【6月更文挑战第19天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
40 3
滚雪球学Java(65):深入理解Java中的Map接口:实现原理剖析
|
4月前
|
存储 缓存 算法
滚雪球学Java(62):HashSet的底层实现原理解析
【6月更文挑战第16天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
39 3
滚雪球学Java(62):HashSet的底层实现原理解析
|
4月前
|
存储 Java 测试技术
滚雪球学Java(61):从源码角度解读Java Set接口底层实现原理
【6月更文挑战第15天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
57 1
滚雪球学Java(61):从源码角度解读Java Set接口底层实现原理