使用 nginx 作为 HTTP 负载均衡器
| 负载均衡方法 默认负载均衡配置 最少连接负载均衡 会话保持 加权负载均衡 健康检查 延伸阅读 |
简介
在多个应用程序实例之间进行负载均衡是一种常用的技术,用于优化资源利用率、最大化吞吐量、降低延迟并确保配置的容错能力。
通过将 nginx 作为高效的 HTTP 负载均衡器,可以向多个应用服务器分发流量,从而提升 Web 应用的性能、可扩展性和可靠性。
负载均衡方法
nginx 支持以下负载均衡机制(或方法):
- 轮询(round-robin) — 对应用服务器的请求以轮询方式分发;
- 最少连接(least-connected) — 下一个请求被分配给活动连接数最少的服务器;
- IP 哈希(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 上运行。当未特别配置负载均衡方法时,默认使用轮询方式。所有请求都会被代理到服务器组 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_conn 指令时,nginx 会激活最少连接负载均衡。
upstream myapp1 {
least_conn;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
会话保持
请注意,在使用轮询或最少连接负载均衡时,每个后续的客户端请求都可能被分发到不同的服务器。无法保证同一客户端始终会被导向同一台服务器。
如果需要将客户端绑定到特定的应用服务器(换句话说,使客户端的会话保持“粘性”或“持久化”,即始终尝试选择同一台服务器),则可以使用 ip-hash 负载均衡机制。
使用 ip-hash 时,客户端的 IP 地址被用作哈希键,以确定服务器组中哪台服务器应处理该客户端的请求。此方法确保来自同一客户端的请求始终被导向同一台服务器,除非该服务器不可用。
要配置 ip-hash 负载均衡,只需在服务器(upstream)组配置中添加 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,1 个请求导向 srv2,另 1 个请求导向 srv3。
在较新版本的 nginx 中,类似地可以将权重用于最少连接和 ip-hash 负载均衡。
健康检查
nginx 的反向代理实现包括带内(或被动)服务器健康检查。如果来自特定服务器的响应返回错误,nginx 会将该服务器标记为失败,并在一段时间内尽量避免将后续的入站请求发送给该服务器。
max_fails 指令设置在 fail_timeout 时间内与服务器通信时允许的连续失败尝试次数。max_fails 的默认值为 1。将其设置为 0 则表示禁用该服务器的健康检查。fail_timeout 参数还定义了服务器被标记为失败的时间长度。在服务器失败后的 fail_timeout 时间间隔过后,nginx 将开始使用真实的客户端请求温和地探测该服务器。如果探测成功,该服务器将被标记为存活状态。
延伸阅读
此外,还有更多指令和参数可用于控制 nginx 中的服务器负载均衡,例如 proxy_next_upstream、backup、down 和 keepalive。更多信息请参阅我们的参考文档。
最后但同样重要的一点是,应用程序负载均衡、应用程序健康检查、活动监控以及服务器组的动态重配置功能均包含在我们付费的 NGINX Plus 订阅中。