zoukankan      html  css  js  c++  java
  • 【分布式】load balance 04-java 从零手写实现负载均衡

    负载均衡系列专题

    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

    公众号

  • 相关阅读:
    201871010114李岩松《面向对象程序设计(java)》第十二周学习总结
    201871010114李岩松《面向对象程序设计(java)》第十六周学习总结
    201871010114李岩松《面向对象程序设计(java)》第八周学习总结
    201871010114李岩松《面向对象程序设计(java)》第七周学习总结
    201871010114李岩松《面向对象程序设计(java)》第六、七周学习总结
    一分钟秒解数据库三大范式
    反射机制获取类的方法
    hashMap和hashTable的区别
    ssm+maven 框架整合
    Hibernate从零开始的反向工程
  • 原文地址:https://www.cnblogs.com/houbbBlogs/p/13167927.html
Copyright © 2011-2022 走看看