使用 Nginx 作为 HTTP 负载均衡器

Introduction

跨多个应用程序实例的负载平衡是一种用于优化资源利用率,最大化吞吐量,减少延迟和确保容错配置的常用技术。

可以将 nginx 用作非常有效的 HTTP 负载平衡器,以将流量分配到多个应用程序服务器,并使用 nginx 改善 Web 应用程序的性能,可伸缩性和可靠性。

负载均衡方法

nginx 支持以下负载平衡机制(或方法):

  • 循环-对应用服务器的请求以循环方式分发,

  • 最少连接-将下一个请求分配给活动连接数量最少的服务器,

  • ip-hash —哈希函数用于确定应为下一个请求选择哪个服务器(基于客户端的 IP 地址)。

默认负载平衡配置

使用 nginx 进行负载平衡的最简单配置如下所示:

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

在上面的示例中,同一应用程序的 3 个实例在 srv1-srv3 上运行。如果未特别配置负载平衡方法,则默认为循环。所有请求均为proxied到服务器组 myapp1,并且 nginx 应用 HTTP 负载平衡来分发请求。

nginx 中的反向代理实现包括 HTTP,HTTPS,FastCGI,uwsgi,SCGI,memcached 和 gRPC 的负载平衡。

要为 HTTPS(而非 HTTP)配置负载平衡,只需使用“ https”作为协议。

为 FastCGI,uwsgi,SCGI,memcached 或 gRPC 设置负载平衡时,请分别使用fastcgi_passuwsgi_passscgi_passmemcached_passgrpc_pass指令。

最少连接的负载平衡

另一个负载平衡原则是连接最少的。最少连接允许在某些请求需要较长时间才能完成的情况下更公平地控制应用程序实例上的负载。

使用最少连接的负载平衡,nginx 将尝试不使繁忙的应用程序服务器因过多的请求而过载,而是将新的请求分配给不太繁忙的服务器。

least_conn指令用作服务器组配置的一部分时,将激活 nginx 中的最少连接负载均衡:

upstream myapp1 {
        least_conn;
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

Session persistence

请注意,使用循环或最少连接的负载平衡时,每个后续客户端的请求都可能分配到不同的服务器。无法保证将同一客户端始终定向到同一服务器。

如果需要将客户端绑定到特定的应用程序服务器(换句话说,就始终尝试选择特定服务器而言,使客户端的会话为“粘性”或“持久性”),则可以使用 ip-hash 负载平衡机制用过的。

使用 ip-hash,客户端的 IP 地址用作哈希密钥,以确定应为客户端的请求选择服务器组中的哪个服务器。此方法可确保将来自同一客户端的请求始终定向到同一服务器,除非该服务器不可用。

要配置 ip-hash 负载平衡,只需将ip_hash指令添加到服务器(上游)组配置中:

upstream myapp1 {
    ip_hash;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

加权负载均衡

还可以通过使用服务器权重来进一步影响 nginx 负载平衡算法。

在上面的示例中,未配置服务器权重,这意味着所有指定的服务器都被视为对特定负载平衡方法具有同等资格。

特别是对于循环,这还意味着在服务器之间的请求分配大致相等-前提是存在足够的请求,并且当请求以统一的方式处理并足够快地完成时。

当为服务器指定weight参数时,权重将作为负载平衡决策的一部分。

upstream myapp1 {
        server srv1.example.com weight=3;
        server srv2.example.com;
        server srv3.example.com;
    }

使用此配置,每 5 个新请求将按以下方式分布在应用程序实例中:3 个请求将定向到 srv1,一个请求将定向到 srv2,另一个将定向到 srv3.

类似地,在最新版本的 nginx 中,可以使用权重最少的连接和 ip-hash 负载平衡。

Health checks

nginx 中的反向代理实现包括带内(或被动)服务器运行状况检查。如果来自特定服务器的响应失败并出现错误,nginx 会将其标记为失败服务器,并尝试避免为一段时间的后续入站请求选择该服务器。

max_fails伪指令设置应在fail_timeout期间进行的与服务器通信的连续失败尝试次数。默认情况下,max_fails设置为 1.当它设置为 0 时,将禁用此服务器的运行状况检查。 fail_timeout参数还定义服务器将被标记为故障的时间。在服务器发生故障后间隔fail_timeout之后,nginx 将开始使用实时客户端的请求来正常探测服务器。如果探测成功,则将服务器标记为活动服务器。

Further reading

另外,在 nginx 中还有更多指令和参数可以控制服务器负载平衡,例如proxy_next_upstreambackupdownkeepalive。有关更多信息,请检查我们的reference documentation

最后但并非最不重要的一点是,应用程序负载平衡应用程序运行状况检查activity monitoringon-the-fly reconfiguration服务器组是我们的 NGINX Plus 付费订阅的一部分。

以下文章更详细地介绍了 NGINX Plus 的负载平衡: