负载均衡系列专题

01-负载均衡基础知识

02-一致性 hash 原理

03-一致性哈希算法 java 实现

04-负载均衡算法 java 实现

本节我们来看一下如何实现一负载均衡框架。

源码

核心接口定义

public interface ILoadBalance {

    /**
* 选择下一个节点
*
* 返回下标
* @param context 上下文
* @return 结果
* @since 0.0.1
*/
IServer select(final ILoadBalanceContext context); }

1. 随机策略

public class LoadBalanceRandom extends AbstractLoadBalance{

    public LoadBalanceRandom(List<IServer> servers) {
super(servers);
} @Override
protected IServer doSelect(ILoadBalanceContext context) {
Random random = ThreadLocalRandom.current();
int nextIndex = random.nextInt(servers.size());
return servers.get(nextIndex);
} }

2. 轮训

public class LoadBalanceRoundRobbin extends AbstractLoadBalance {

    /**
* 位移指针
* @since 0.0.1
*/
private final AtomicLong indexHolder = new AtomicLong(); public LoadBalanceRoundRobbin(List<IServer> servers) {
super(servers);
} @Override
protected IServer doSelect(ILoadBalanceContext context) {
long index = indexHolder.getAndIncrement();
int actual = (int) (index % servers.size());
return servers.get(actual);
} }

3. 有权重的轮训

这个需要对数据进行初始化处理,计算数组的最大公约数。

public class LoadBalanceWeightRoundRobbin extends AbstractLoadBalance {

    /**
* 位移指针
* @since 0.0.1
*/
private final AtomicLong indexHolder = new AtomicLong(); /**
* 处理后的列表
* @since 0.0.1
*/
private final List<IServer> actualList = new ArrayList<>(); public LoadBalanceWeightRoundRobbin(List<IServer> servers) {
super(servers); // 初始化真实列表
this.init(servers);
} @Override
protected IServer doSelect(ILoadBalanceContext context) {
long index = indexHolder.getAndIncrement(); // 基于真实的列表构建
int actual = (int) (index % actualList.size());
return actualList.get(actual);
} /**
* 初始化
* @param serverList 服务列表
* @since 0.0.1
*/
private void init(final List<IServer> serverList) {
//1. 过滤掉权重为 0 的机器
List<IServer> notZeroServers = CollectionUtil.filterList(serverList, new IFilter<IServer>() {
@Override
public boolean filter(IServer iServer) {
return iServer.weight() <= 0;
}
}); //2. 获取权重列表
List<Integer> weightList = CollectionUtil.toList(notZeroServers, new IHandler<IServer, Integer>() {
@Override
public Integer handle(IServer iServer) {
return iServer.weight();
}
}); //3. 获取最大的权重
int maxDivisor = MathUtil.ngcd(weightList); //4. 重新计算构建基于权重的列表
for(IServer server : notZeroServers) {
int weight = server.weight(); int times = weight / maxDivisor;
for(int i = 0; i < times; i++) {
actualList.add(server);
}
}
} }

4. 普通哈希

public class LoadBalanceCommonHash extends AbstractLoadBalanceHash {

    public LoadBalanceCommonHash(List<IServer> servers, IHash hash) {
super(servers, hash);
} @Override
protected IServer doSelect(ILoadBalanceContext context) {
final String hashKey = context.hashKey(); int hashCode = Math.abs(hash.hash(hashKey));
int index = servers.size() % hashCode;
return servers.get(index);
} }

5. 一致性哈希

这里将我们前面实现的一致性哈希,与负载均衡结合。

public class LoadBalanceConsistentHash extends AbstractLoadBalanceHash {

    /**
* 一致性 hash 实现
* @since 0.0.1
*/
private final IConsistentHashing<IServer> consistentHashing; public LoadBalanceConsistentHash(List<IServer> servers, IHash hash) {
super(servers, hash); this.consistentHashing = ConsistentHashingBs
.<IServer>newInstance()
.hash(hash)
.nodes(servers)
.build();
} @Override
protected IServer doSelect(ILoadBalanceContext context) {
final String hashKey = context.hashKey(); return consistentHashing.get(hashKey);
} }

后期 Road-Map

还有基于系统最小压力,最小连接的实现,暂时没有放在这里。

后续将加入对应的实现。

完整开源代码

其他还有一些引导类等辅助工具。

完整代码参见 load-balance

【分布式】load balance 04-java 从零手写实现负载均衡的更多相关文章

  1. Neutron: Load Balance as a Service(LBaaS)负载均衡

    load balancer 负责监听外部的连接,并将连接分发到 pool member.    LBaaS 有三个主要的概念: Pool Member,Pool 和 Virtual IP Pool M ...

  2. Azure Load Balancer(二) 基于内部的负载均衡来转发为访问请求

    一,引言 上一节,我们使用 Azure Load Balancer 类型为外部的,来转发我们的 Web 服务.今天我们看看另一种类型为 “Internal” 的 Azure Load Balancer ...

  3. 分布式的几件小事(四)dubbo负载均衡策略和集群容错策略

    1.dubbo负载均衡策略 ①random loadbalance 策略 默认情况下,dubbo是random loadbalance 随机调用实现负载均衡,可以对provider不同实例设置不同的权 ...

  4. 【mq】从零开始实现 mq-07-负载均衡 load balance

    前景回顾 [mq]从零开始实现 mq-01-生产者.消费者启动 [mq]从零开始实现 mq-02-如何实现生产者调用消费者? [mq]从零开始实现 mq-03-引入 broker 中间人 [mq]从零 ...

  5. OpenStack Neutron 之 Load Balance

    OpenStack Neutron 之 Load Balance 负载均衡(Load Balance)是 OpenStack Neutron 支持的功能之一.负载均衡能够将网络请求分发到多个实际处理请 ...

  6. 章文嵩博士和他背后的负载均衡(LOAD BANLANCER)帝国

    案首语: 阿里集团技术大牛,@正明,淘宝基础核心软件研发负责人.LVS创始人.阿里云首席科学家章文嵩博士从阿里离职,去追求技术人生另一段历程,让阿里像我一样的很多热爱技术的工程师都有一丝牵动和感触. ...

  7. 负载均衡的几种算法Java实现代码

    轮询 package class2.zookeeper.loadbalance; import java.util.ArrayList; import java.util.HashMap; impor ...

  8. 负载均衡(Load Balancing)学习笔记(二)

    概述 文章负载均衡(Load Balancing)学习笔记(一) 讲述了负载均衡的一般性原理,本文继续介绍常见的实现负载均衡的方法. HTTP重定向 HTTP重定向服务器是一台普通的Web服务器,用户 ...

  9. java 从零开始手写 RPC (04) -序列化

    序列化 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 java 从零开始手写 RPC (03) 如何实 ...

  10. Vertica7 Native Connection Load Balance

    原文链接:Vertica7 Native Connection Load Balance 在Vertica7曾经的版本号中,Vertica是通过Linux的Virtual IP来实现连接的负载均衡的, ...

随机推荐

  1. 【面试题精讲】你知道MySQL中有哪些隔离级别吗

    有时博客内容会有变动,首发博客是最新的,其他博客地址可能未同步,请认准https://blog.zysicyj.top 首发博客地址 系列文章地址 脏读(Dirty Read)是指一个事务读取到了另一 ...

  2. [转帖]SQL Server中查询CPU占用高的SQL语句

    本文导读:触发器造成死锁.作业多且频繁.中间表的大量使用.游标的大量使用.索引的设计不合理.事务操作频繁.SQL语句设计不合理,都会造成查询效率低下.影响服务器性能的发挥.我们可以使用sql serv ...

  3. [转帖]一篇来自网络的关于“enqueue”events的简短参考

    https://www.cnblogs.com/lhdz_bj/p/8716701.html 仅供自己和各位同学参考: Enqueue Type Description enq: AD - alloc ...

  4. [转帖]Linux内核线程kthread简介【最好的一篇!】

    https://zhuanlan.zhihu.com/p/581587583 Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求).内核需要多个执行流并行,为了 ...

  5. CentOS7升级Glibc到超过2.17版本无法启动的解决办法

    CentOS7升级Glibc到超过2.17版本无法启动的解决办法 背景 今天有同事告知服务器宕机无法启动. 提示信息为: [sda] Assuming drive cache: write throu ...

  6. SUBMIT指定用户名错误

    1.SUBMIT说明 在ABAP中,SUBMIT关键字用于运行另一个ABAP程序.通过SUBMIT关键字,可以在当前程序内部调用其他程序,而无需关闭当前程序. SUBMIT语句的一般语法如下: &qu ...

  7. Git、Github、Gitlab与Gitee

    Git.Github.Gitlab与Gitee之间的关系 Git 是一种版本控制系统,是一个命令,是一种工具,有点像cmd(命令行工具). Github 是一个基于git实现在线代码托管的仓库,向互联 ...

  8. 【主流技术】聊一聊对 Mybatis Plus 的理解与应用

    前言 mybatis plus是一个mybatis的增强工具,在其基础上只做增强不做改变.作为开发中常见的第三方组件,学习并应用在项目中可以节省开发时间,提高开发效率. 官方文档地址:MyBatis- ...

  9. Flask 实现Token认证机制

    在Flask框架中,实现Token认证机制并不是一件复杂的事情.除了使用官方提供的flask_httpauth模块或者第三方模块flask-jwt,我们还可以考虑自己实现一个简易版的Token认证工具 ...

  10. 5.2 Windows驱动开发:内核取KERNEL模块基址

    模块是程序加载时被动态装载的,模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程 ...