使用 nginx 作为 HTTP 负载均衡器

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

可以将 nginx 用作非常有效的 HTTP 负载均衡器,将流量分配到多个应用程序服务器,并使用 nginx 提高 Web 应用程序的性能、可扩展性和可靠性。

负载均衡方法

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

  • round-robin(轮询):对应用服务器的请求以循环方式分发

  • least-connected(最少连接):下一个请求被分配给活动连接数最少的服务器

  • 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 上运行。当没有特别指定负载均衡方式时,默认采用轮询(round-robin)。所有请求都代理到服务器组 myapp1,nginx 应用 HTTP 负载均衡来分发请求。

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

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

为 FastCGI、uwsgi、SCGI、memcached 或 gRPC 设置负载平衡时,请分别使用 fastcgi_pass、uwsgi_pass、scgi_pass、memcached_pass 和 grpc_pass 指令。

最少连接负载均衡配置

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

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

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

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

session 持久化

请注意,通过循环(round-robin)或最少连接(least-connected)负载平衡,每个后续客户端的请求可能会分发到不同的服务器。无法保证始终将同一客户端定向到同一服务器。

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

使用 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 中还可以通过使用服务器权重进一步影响 nginx 负载平衡算法。

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

特别是对于轮询(round-robin),这也意味着请求在服务器之间的分布或多或少是相等的 ———— 如果有足够的请求,并且请求以统一的方式处理并足够快地完成。

当为服务器指定 weight 参数时,weight 被视为负载均衡决策的一部分:

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

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

在最近版本的 nginx 中,同样可以使用具有最少连接(least-connected)和 ip-hash 负载均衡的权重。

监控检查

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

max_fails 指令设置在 fail_timeout 期间应该发生的与服务器通信的连续不成功尝试次数。默认情况下,max_fails 设置为 1。当它设置为 0 时,将禁用此服务器的运行状况检查。

fail_timeout 参数定义了服务器被标记为失败的时间。在服务器故障后的 fail_timeout 间隔时间后,nginx 将开始使用实时客户端的请求优雅地探测服务器。如果探测成功,则服务器被标记为活动服务器。

进一步阅读

此外,在 nginx 中还有更多控制服务器负载均衡的指令和参数,例如:proxy_next_upstream、backup、down 和 keepalive。

最后但并非最不重要的一点是,应用程序负载均衡(application load balancing)、应用程序健康检查(application health checks)、活动监控(activity monitoring)和服务器组的动态重新配置作为我们付费 Nginx Plus 订阅的一部分进行提供。

以下文章将更详细地描述了 Nginx Plus 的负载均衡:

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号