负载均衡是怎么做的?

负载均衡

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

负载均衡算法

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

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

public interface LoadBalanceSelector {
    N select(C c);
}

@RequiredArgsConstructor
public abstract class AbstractLoadBalanceSelector implements LoadBalanceSelector {
    
    private final Supplier> supplier;
    private final Predicate predicate;
    
    @Override
    public N select(C c) {
        List 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 candidates);
}

public class RandomLoadBalanceSelector extends AbstractLoadBalanceSelector {
    
    public RandomLoadBalanceSelector(Supplier> supplier, Predicate predicate) {
        super(supplier, predicate);
    }
    
    @Override
    protected int getIndex(List candidates) {
        return (int) (ThreadLocalRandom.current().nextDouble() * candidates.size());
    }
}

public class RoundRobinLoadBalanceSelector extends AbstractLoadBalanceSelector {
    
    private static AtomicInteger idx = new AtomicInteger(0);
    
    public RoundRobinLoadBalanceSelector(Supplier> supplier, Predicate predicate) {
        super(supplier, predicate);
    }
    
    @Override
    protected int getIndex(List candidates) {
        return 0x7fffffff & idx.incrementAndGet();
    }
}

public enum LoadBalanceStrategyEnums {
    
    RoundRobin,
    
    RANDOM,
}

public final class LoadBalanceSelectors {
    
    private LoadBalanceSelectors() {
    
    }
    
    public static  LoadBalanceSelector of(Supplier> supplier, Predicate predicate,
                                                      LoadBalanceStrategyEnums loadBalanceStrategy) {
        
        if (loadBalanceStrategy == LoadBalanceStrategyEnums.RANDOM) {
            return new RandomLoadBalanceSelector(supplier, predicate);
        }
        return new RoundRobinLoadBalanceSelector(supplier, predicate);
    }
}

完整版代码

参考文章:

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

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

你可能感兴趣的:(负载均衡是怎么做的?)