美文网首页
负载均衡是怎么做的?

负载均衡是怎么做的?

作者: 育王净量 | 来源:发表于2019-03-05 20:16 被阅读0次

    负载均衡

    负载均衡是实现分布式系统高可用的方式之一;负载均衡策略实现了把高并发的流量分摊在其后的服务器集群上;常见的,有基于F5硬件负载均衡设备、基于DNS的负载均衡设备(根据请求IP,选择就近的服务集群提供服务,DNS的缓存不能使负载均衡策略立即生效)、基于软件LVS的负载均衡设备(分两种:七层应用层的Nginx负载均衡、四层传输层的流量分发)。

    负载均衡算法

    常见负载均衡算法有:轮询策略(顺序轮询和随机轮询)、负载度策略、响应策略、哈希策略。实际项目中使用轮询策略的居多;

    基于轮询策略的负载均衡算法实现

    public interface LoadBalanceSelector<N, C> {
        N select(C c);
    }
    
    @RequiredArgsConstructor
    public abstract class AbstractLoadBalanceSelector<N, C> implements LoadBalanceSelector<N, C> {
        
        private final Supplier<List<N>> supplier;
        private final Predicate<N> predicate;
        
        @Override
        public N select(C c) {
            List<N> candidates = supplier.get();
            if (CollectionUtils.isEmpty(candidates)) {
                return null;
            } else if (candidates.size() == 1) {
                return predicate.test(candidates.get(0)) ? candidates.get(0) : null;
            }
            
            N candidate = null;
            int idx = getIndex(candidates);
            for (int i = 0; i < candidates.size(); i++) {
                N n = candidates.get((i + idx) % candidates.size());
                if (predicate.test(n)) {
                    candidate = n;
                }
            }
            return candidate;
        }
        
        abstract protected int getIndex(List<N> candidates);
    }
    
    public class RandomLoadBalanceSelector<N, C> extends AbstractLoadBalanceSelector<N, C> {
        
        public RandomLoadBalanceSelector(Supplier<List<N>> supplier, Predicate<N> predicate) {
            super(supplier, predicate);
        }
        
        @Override
        protected int getIndex(List<N> candidates) {
            return (int) (ThreadLocalRandom.current().nextDouble() * candidates.size());
        }
    }
    
    public class RoundRobinLoadBalanceSelector<N, C> extends AbstractLoadBalanceSelector<N, C> {
        
        private static AtomicInteger idx = new AtomicInteger(0);
        
        public RoundRobinLoadBalanceSelector(Supplier<List<N>> supplier, Predicate<N> predicate) {
            super(supplier, predicate);
        }
        
        @Override
        protected int getIndex(List<N> candidates) {
            return 0x7fffffff & idx.incrementAndGet();
        }
    }
    
    public enum LoadBalanceStrategyEnums {
        
        RoundRobin,
        
        RANDOM,
    }
    
    public final class LoadBalanceSelectors {
        
        private LoadBalanceSelectors() {
        
        }
        
        public static <N, C> LoadBalanceSelector<N, C> of(Supplier<List<N>> supplier, Predicate<N> predicate,
                                                          LoadBalanceStrategyEnums loadBalanceStrategy) {
            
            if (loadBalanceStrategy == LoadBalanceStrategyEnums.RANDOM) {
                return new RandomLoadBalanceSelector<N,C>(supplier, predicate);
            }
            return new RoundRobinLoadBalanceSelector<N,C>(supplier, predicate);
        }
    }
    

    完整版代码

    参考文章:

    1. 分布式系统关注点——如何去实施「负载均衡」

    2. 不懂高性能的负载均衡设计?没关系,架构师带你飞

    相关文章

      网友评论

          本文标题:负载均衡是怎么做的?

          本文链接:https://www.haomeiwen.com/subject/jiqauqtx.html