Nginx 负载均衡 (Load Balancing) 配置详细指南


哈喽,大家好!今天我们来聊一个在 Web 服务架构中非常重要的话题——负载均衡。当你的网站或应用访问量越来越大时,单台服务器迟早会不堪重负。这时候,负载均衡就能派上大用场,它就像一个聪明的交通指挥官,把如潮水般涌来的网络请求,合理地分配给后方的多台服务器处理,从而保证服务的高可用和高性能。

而 Nginx,作为一款高性能的 Web 服务器和反向代理服务器,恰好内置了非常强大且易于配置的负载均衡功能。 下面,我们就一步步来揭开 Nginx 负载均衡的神秘面纱。

什么是负载均衡?

简单来说,负载均衡就是将工作量(在这里是网络请求)分摊到多个操作单元(服务器)上执行。 好处显而易见:

  • 提高性能:多台服务器一起干活,总比一台服务器单打独斗要快得多。
  • 提升可用性:即使后方某台服务器宕机了,Nginx 会自动把它从服务列表中剔除,将请求转发给其他健康的服务器,保证网站服务不中断。
  • 便于扩展:当业务增长时,只需要向服务器集群中添加新的服务器,就能轻松应对增长的流量。

Nginx 负载均衡的核心:upstream 模块

Nginx 实现负载均衡的核心就在于 upstream 模块。 你可以把它理解成一个服务器组,在这个组里,你可以定义一组后端服务器的地址。

一个最基础的负载均衡配置,看起来是这样的:

http {
    # 定义一个名为 "backend" 的上游服务器组
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com;
    }

    # 定义一个虚拟主机
    server {
        listen 80;

        location / {
            # 将所有请求转发到 "backend" 服务器组
            proxy_pass http://backend;
        }
    }
}

代码解析:

  • http { ... }: 这是 Nginx 配置的主块,所有的 HTTP 相关配置都在这里面。
  • upstream backend { ... }: 这里我们定义了一个名为 backend 的服务器组。 backend 这个名字可以随便取,只要后面 proxy_pass 指令引用的是同一个名字就行。
  • server backend1.example.com;: 在 upstream 块中,通过 server 指令定义了后端服务器的地址,可以是域名也可以是 IP 地址。这里我们定义了三台服务器。
  • server { ... }: 这是定义一个虚拟主机的配置块。
  • location / { ... }: 匹配所有进入的请求。
  • proxy_pass http://backend;: 这是关键!它告诉 Nginx 将匹配到的请求,转发给我们上面定义的那个名为 backend 的服务器组。

玩转 Nginx 的负载均衡策略

Nginx 不仅仅是简单地把请求依次发给后端服务器,它还提供了多种智能的分配策略(也叫负载均衡算法),以适应不同的业务场景。

1. 轮询 (Round Robin) - 默认策略

这是 Nginx 最基础也是默认的策略。请求会按照时间顺序,逐一、循环地分配给后端服务器。 这种方式非常公平,适用于后端服务器性能都差不多的情况。

配置案例:

upstream backend {
    # 不需要任何额外指令,默认就是轮询
    server 192.168.1.100;
    server 192.168.1.101;
}

第一个请求给 100,第二个给 101,第三个又给 100,以此类推。

2. 加权轮询 (Weighted Round Robin) - 给能者多加担子

如果你的服务器性能有高有低,比如一台是高配物理机,一台是低配云主机,那么用简单的轮询就不太合适了。这时,weight(权重)参数就派上用场了。 你可以给性能高的服务器分配更高的权重,这样它就能接收到更多的请求。

配置案例:

upstream backend {
    server 192.168.1.100 weight=3; # 高配服务器
    server 192.168.1.101 weight=1; # 普通服务器
}

解析:

在这个例子中,192.168.1.100 的权重是 3192.168.1.101 的权重是 1(默认不写就是1)。 这样一来,在每 4 个请求中,大约有 3 个会分配给第一台服务器,1 个会分配给第二台服务器,完美实现了“能者多劳”。

3. IP 哈希 (ip_hash) - 让同一个用户始终访问同一台服务器

有些场景下,我们需要确保来自同一个客户端的请求,始终由同一台后端服务器处理。最典型的例子就是需要维持 session 会话的应用(比如用户登录状态)。ip_hash 策略就是为此而生的。它会根据请求来源的 IP 地址进行哈希计算,然后将请求固定分配给某一台服务器。

配置案例:

upstream backend {
    ip_hash;
    server 192.168.1.100;
    server 192.168.1.101;
}

解析:

只需要在 upstream 块里加上 ip_hash; 这一行,Nginx 就会采用 IP 哈希算法。这样,只要用户的 IP 地址不变,他所有的请求都会落到同一台后端服务器上,解决了 session 共享的问题。

4. 最少连接 (Least Connections) - 谁最闲,活给谁

这个策略非常智能,它会把新的请求优先分配给当前活动连接数最少的那台服务器。 这对于处理耗时较长请求的场景非常有用,可以有效避免某些服务器因为处理慢请求而导致连接堆积,而其他服务器却很空闲的情况。

配置案例:

upstream backend {
    least_conn;
    server 192.168.1.100;
    server 192.168.1.101;
}

解析:

加上 least_conn; 指令即可开启。当一个新请求到来时,Nginx 会检查哪台服务器的当前连接数最少,就把请求发给谁,非常高效。

注意: 还有一些如 fairurl_hash 等第三方负载均衡策略,需要额外安装模块,这里就不做展开了。

必不可少的健康检查

配置了负载均衡后,我们还需要一个机制来确保后端服务器是“活着的”。如果一台服务器挂了,Nginx 应该能及时发现并停止向它发送请求。这就是健康检查。

upstreamserver 指令中,我们可以配置两个非常有用的参数:

  • max_fails: 在 fail_timeout 时间内,允许的最大失败尝试次数。默认是 1。
  • fail_timeout: 服务器被标记为不可用之前的超时时间,也表示服务器被标记为不可用后,多长时间内 Nginx 会再次尝试连接它。默认是 10 秒。

配置案例:

upstream backend {
    server 192.168.1.100 max_fails=3 fail_timeout=30s;
    server 192.168.1.101;
}

解析:

这行配置意味着:如果在 30 秒内,Nginx 尝试连接 192.168.1.100 失败了 3 次,那么 Nginx 就会认为这台服务器“挂了”,在接下来的 30 秒内不会再把任何请求发给它。30 秒后会再次尝试,如果恢复了就重新加入服务列表。

总结

到这里,相信你已经对 Nginx 负载均衡的配置有了一个清晰的认识。它通过简单的 upstreamproxy_pass 指令,配合多种负载均衡策略和健康检查机制,就能轻松构建一个高可用、可扩展的 Web 服务架构。

从最简单的轮询,到考虑服务器性能的加权轮询,再到维持会话的 IP 哈希和智能分配的最少连接,Nginx 提供了丰富的工具集让我们应对各种复杂的业务需求。赶快动手试试,为你的应用加上强大的负载均衡能力吧!


  目录