云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

分享一下面试被问了负载均衡的这些问题

jxf315 2025-05-03 14:51:25 教程文章 1 ℃

负载均衡的类型

负载均衡可以分为两种类型:

  1. 服务器端负载平衡
  2. 客户端负载平衡

1.服务器端负载平衡

在服务器端负载平衡中,服务实例部署在多个服务器上,然后它们前面放置一个负载均衡器。通常有硬件负载平衡器——F5以及软件负载均衡-Nginx。所有传入的请求流量首先作为中间组件到达此负载均衡器。然后,它根据某种算法来决定将特定请求定向到哪个服务器。

服务器端负载平衡的缺点

  1. 服务器端负载均衡器就像是一个单点故障,就像它失败一样,由于只有负载均衡器具有服务器列表,因此微服务的所有实例都变得不可访问。
  2. 由于每个微服务将有一个单独的负载均衡器,因此系统整体复杂性增加,并且变得难以管理
  3. 随着请求的跳数从负载均衡器的一跳增加到两跳,一跳到负载均衡器,然后另一跳从负载均衡器跳转到微服务,网络延迟就会增加。

2.客户端负载均衡

该服务的实例部署在多个服务器上。负载均衡器的逻辑是客户端本身的一部分,它包含服务器列表,并根据某种算法决定特定请求必须定向到哪台服务器。这些客户端负载平衡器也称为软件负载均衡器

客户端负载均衡的缺点

  1. 负载均衡器的逻辑与微服务代码混合在一起。

根据官方网站,Netflix的Ribbon是一个进程间通信(远程过程调用)库,内置客户端(软件)负载均衡器,是Netflix开源软件(Netflix OSS)的一部分。负载均衡:它提供客户端负载均衡功能。容错:它可以用来确定服务器是否正常运行,也可以检测那些宕机的服务器,从而忽略它们以发送进一步的请求。可配置的负载均衡规则:默认情况下,ribbon使用RoundRobinRule在服务器之间分配请求

如下是实际源码中的实现方式:

 public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        } else {
            Server server = null;
            int count = 0;

            while(true) {
                if (server == null && count++ < 10) {
                    List<Server> reachableServers = lb.getReachableServers();
                    List<Server> allServers = lb.getAllServers();
                    int upCount = reachableServers.size();
                    int serverCount = allServers.size();
                    if (upCount != 0 && serverCount != 0) {
                        int nextServerIndex = this.incrementAndGetModulo(serverCount);
                        server = (Server)allServers.get(nextServerIndex);
                        if (server == null) {
                            Thread.yield();
                        } else {
                            if (server.isAlive() && server.isReadyToServe()) {
                                return server;
                            }

                            server = null;
                        }
                        continue;
                    }

                    log.warn("No up servers available from load balancer: " + lb);
                    return null;
                }

                if (count >= 10) {
                    log.warn("No available alive servers after 10 tries from load balancer: " + lb);
                }

                return server;
            }
        }
    }

 private int incrementAndGetModulo(int modulo) {
        int current;
        int next;
        do {
            current = this.nextServerCyclicCounter.get();
            next = (current + 1) % modulo;
        } while(!this.nextServerCyclicCounter.compareAndSet(current, next));

        return next;
    }

除此之外,还有权重轮询策略,随机轮询策略等。我们还可以根据需要自定义规则。它支持多种协议,如HTTP, TCP, UDP等。

最近发表
标签列表