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

    公众号

  • 相关阅读:
    FTP的搭建与虚拟目录作用<之简单讲解>
    Android NDK: Application targets deprecated ABI(s): armeabi Open File
    Java:集合与数组转换
    优雅的运用 Kotlin 的 null safety 特性,而不要简单的直接用 !!双感叹号
    Android Studio安装Kotlin插件
    ViewPager一屏显示多个item,及边缘滑动事件优化
    卡片式ViewPager,一屏展示多个pager item,设置高度不一致的tabBar
    MPAndroidChart的具体属性方法
    android studio 解析Excel数据格式导入poi-3.17.jar时的一系列报错及处理Failed resolution of: Ljavax/xml/stream/XMLEventFactory,duplicate entry: org/apache/xmlbeans/xml/stream/Location.class,GC overhead limit exceeded
    android调用系统的自定义裁剪后得到的图片不清晰,使用MediaStore.EXTRA_OUTPUT获取缓存下的清晰图片
  • 原文地址:https://www.cnblogs.com/houbbBlogs/p/13167927.html
Copyright © 2011-2022 走看看