Nginx 实现负载均衡主要有以下几种方法:

轮询(Round - Robin)

  • 原理

    • 轮询是 Nginx 默认的负载均衡算法。它按照顺序依次将客户端的请求分配到后端的服务器组中。例如,有服务器 A、B、C,当第一个请求来时分配到 A,第二个请求分配到 B,第三个请求分配到 C,第四个请求又回到 A,如此循环。
  • 配置示例

    • nginx.confhttp块中定义一个upstream服务器组:
     upstream backend {
         server server1.example.com;
         server server2.example.com;
         server server3.example.com;
     }
  • 然后在server块中,使用proxy_pass指令将请求转发到这个upstream组:
     server {
         listen       80;
         server_name  example.com;
         location / {
             proxy_pass http://backend;
         }
     }

加权轮询(Weighted Round - Robin)

  • 原理

    • 加权轮询考虑到后端服务器的性能差异。为不同的服务器分配不同的权重值,权重越高的服务器被分配到请求的概率就越大。例如,服务器 A 的权重为 3,服务器 B 的权重为 2,服务器 C 的权重为 1,那么在总共 6 次请求中,服务器 A 可能会被分配到 3 次,服务器 B 被分配到 2 次,服务器 C 被分配到 1 次。
  • 配置示例

    • upstream组中为服务器指定权重:
     upstream backend {
         server server1.example.com weight = 3;
         server server2.example.com weight = 2;
         server server3.example.com weight = 1;
     }

IP 哈希(IP Hash)

  • 原理

    • IP 哈希算法根据客户端的 IP 地址计算一个哈希值,然后根据这个哈希值将请求固定分配到后端的某一台服务器上。这样可以保证来自同一个客户端的请求总是被发送到同一台服务器,适用于有状态的服务,如某些需要保持会话状态的 Web 应用。
  • 配置示例

    • upstream组中使用ip_hash指令:
     upstream backend {
         ip_hash;
         server server1.example.com;
         server server2.example.com;
         server server3.example.com;
     }

最少连接(Least Connections)

  • 原理

    • 最少连接算法会将新的请求分配到当前连接数最少的服务器上。这有助于更均衡地分配负载,特别是在后端服务器的处理能力相近但请求处理时间差异较大的情况下。例如,服务器 A 当前有 10 个连接,服务器 B 有 5 个连接,服务器 C 有 3 个连接,那么新的请求就会被分配到服务器 C。
  • 配置示例

    • upstream组中使用least_conn指令:
     upstream backend {
         least_conn;
         server server1.example.com;
         server server2.example.com;
         server server3.example.com;
     }

基于 URL 的哈希(URL Hash)

  • 原理

    • 根据请求的 URL 计算哈希值,然后根据这个哈希值将请求分配到后端服务器。这样相同的 URL 请求总是被发送到同一台服务器,适用于对缓存有特殊要求的场景,如缓存服务器组,相同的 URL 内容可以在同一台服务器上缓存和处理。
  • 配置示例

    • upstream组中使用hash指令,并指定$uri(表示请求的 URL)作为哈希计算的依据:
     upstream backend {
         hash $uri;
         server server1.example.com;
         server server2.example.com;
         server server3.example.com;
     }