写点什么

使用 NGINX 和 NGINX Plus 实现负载均衡(第 2 部分)

  • 2024-11-20
    北京
  • 本文字数:4316 字

    阅读完需:约 14 分钟

使用 NGINX 和 NGINX Plus 实现负载均衡(第 2 部分)

原文作者:Owen Garrett - F5 产品管理高级总监

原文链接:使用 NGINX 和 NGINX Plus 实现负载均衡(第 2 部分)

转载来源:NGINX 中文官网


《使用 NGINX 和 NGINX Plus 实现负载均衡(第 1 部分)》中,我们设置了一个简单的 HTTP 代理来跨多台 Web 服务器对流量进行负载均衡。本文将介绍 NGINX Plus 具备的一些其他功能:通过 keepalive、健康检查、会话保持、重定向及内容重写来优化性能。


编者按——NGINX Plus Release 5 及更高版本还可以对基于 TCP 的应用进行负载均衡。Release 6 通过增添健康检查、动态重新配置、SSL 终止等功能,显著扩展了 TCP 负载均衡。在 NGINX Plus Release 7 及更高版本中,TCP 负载均衡器具备与 HTTP 负载均衡器一样的功能。Release 9 中引入了对 UDP 负载均衡的支持。

您可以在 stream 上下文(而非 http 上下文)中配置 TCP 和 UDP 负载均衡。由于 HTTP 和 TCP/UDP 之间的固有差异,可用指令和参数略有不同。


快速回顾

回顾一下,这是我们在上一篇文章中创建的配置:

server {    listen 80;
location / { proxy_pass http://backend;
# Rewrite the 'Host' header to the value in the client request, # or primary server name proxy_set_header Host $host;
# Alternatively, put the value in the config: # proxy_set_header Host www.example.com; } }
upstream backend { zone backend 64k; # Use NGINX Plus' shared memory least_conn;
server webserver1 weight=1; server webserver2 weight=4;}
复制代码


本文将介绍一些配置 NGINX 和 NGINX Plus 的简单方法,以提高负载均衡效率。


HTTP keepalive

在 NGINX 或 NGINX Plus 与上游服务器之间启用 HTTP keepalive 可提高性能(通过减少延迟),并降低 NGINX 耗尽临时端口的可能性。


HTTP 协议使用底层 TCP 连接来传输 HTTP 请求并接收 HTTP 响应。HTTP keepalive 连接允许重用这些 TCP 连接,从而避免了为每个请求创建和终止连接的开销:



NGINX 是一个全代理,可独立管理客户端连接(前端 keepalive 连接)和服务器连接(上游 keepalive 连接):



NGINX 会维护 keepalive 连接的“缓存”(一组与上游服务器的空闲 keepalive 连接),当需要将请求转发到上游服务器时,它会使用这些缓存中已建立的 keepalive 连接,而非创建新的 TCP 连接。


这可减少 NGINX 与上游服务器之间的事务延迟,并降低临时端口的使用率,因此 NGINX 能够处理大量流量并对其进行负载均衡。当流量激增时,这些缓存会被清空,在这种情况下,NGINX 将与上游服务器建立新的 HTTP 连接。


对于其他负载均衡工具,该技术有时称为“多路复用”、“连接池”、“连接复用”或“OneConnect”。


您可通过将 proxy_http_version、proxy_set_header 及 keepalive 指令添加到配置中来配置 keepalive 连接缓存:

server {    listen 80;    location / {        proxy_pass http://backend;        proxy_http_version 1.1;        proxy_set_header Connection "";     }}
upstream backend { server webserver1; server webserver2;
# maintain up to 20 idle connections to the group of upstream servers keepalive 20;}
复制代码


健康检查

启用健康检查不仅能够提高负载均衡服务的可靠性,降低最终用户出错率,而且还便于执行常见维护操作。


NGINX Plus 的健康检查功能可用于检测上游服务器的故障。NGINX Plus 使用“综合事务”探测每台服务器,并根据您在 health_check 指令中配置的参数(以及添加 match 参数的情况下,关联的 match 配置块)检查响应:

server {    listen 80;
location / { proxy_pass http://backend;
health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;
# The health checks inherit other proxy settings proxy_set_header Host www.foo.com; }}
match statusok { # Used for /test.php health check status 200; header Content-Type = text/html; body ~ "Server[0-9]+ is alive";}
复制代码


健康检查从其父 location 块继承一些参数。如果在配置中使用运行时变量,这可能会导致出现问题。例如,以下配置适用于实际 HTTP 流量,因为它从客户端请求中提取 Host 请求头的值。但该配置不适用于健康检查所用的综合事务,因为未对这些事务设置 Host 请求头,这意味着综合事务中没有使用 Host 请求头。

location / {    proxy_pass http://backend;
# This health check might not work... health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;
# Extract the 'Host' header from the request proxy_set_header Host $host;}
复制代码


一种好办法是创建一个虚拟 location 块,以静态定义健康检查事务使用的所有参数:

location /internal-health-check1 {    internal; # Prevent external requests from matching this location block
proxy_pass http://backend;
health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok;
# Explicitly set request parameters; don't use run-time variables proxy_set_header Host www.example.com;}
复制代码


会话保持

借助会话保持,可以让无法部署至集群的应用也能实现负载均衡和可靠扩展。存储和复制会话状态的应用可以更高效地运行,帮助提升最终用户性能。


某些应用有时会将状态信息存储到上游服务器,例如当用户将商品放入虚拟购物车或编辑上传的图片时。在这些情况下,您可能希望将来自该用户的所有后续请求都定向到同一服务器。


会话保持指定了请求所须路由到的目标位置,而负载均衡则允许 NGINX 自由选择最佳上游服务器。借助 NGINX Plus 的会话保持功能,这两个进程可以共存:


如果请求符合会话保持规则

那么使用目标上游服务器

否则应用负载均衡算法选择上游服务器


如果会话保持决策因目标服务器不可用而失败,那么 NGINX Plus 会做出负载均衡决策。


最简单的会话保持方法是“sticky cookie”方法,其中 NGINX Plus 在第一个响应中插入一个 cookie,用于标识 sticky 上游服务器:

sticky cookie srv_id expires=1h domain=.example.com path=/;
复制代码


在另一种“sticky 路由”方法中,NGINX 会根据 JSESSIONID cookie 等请求参数选择上游服务器:

upstream backend {   server backend1.example.com route=a;   server backend2.example.com route=b;
# select first non-empty variable; it should contain either 'a' or 'b' sticky route $route_cookie $route_uri;}
复制代码


重写 HTTP 重定向

如果某些重定向被破坏,则您需要重写 HTTP 重定向,特别是当您从代理被重定向到真正的上游服务器时。


当您代理到上游服务器时,服务器在本地地址上发布应用,但您通过另一个地址(代理的地址)访问应用。这些地址通常解析为域名,如果服务器和代理的域名不同,就会出现问题。


例如,在测试环境中,您可能直接(通过 IP 地址)或按 localhost 对代理进行寻址。但上游服务器可能会监听真实域名(例如 www.nginx.com)。当上游服务器发出重定向消息(使用 3xx 状态码和 Location 请求头,或者使用 Refresh 请求头)时,消息中可能包含服务器的真实域名。


NGINX 会尝试拦截并纠正这种最常见的问题。如果您需要全权控制以执行特定重写,请使用 proxy_redirect 指令,如下所示:

proxy_redirect http://staging.mysite.com/ http://$host/;
复制代码


重写 HTTP 响应

有时,您需要重写 HTTP 响应中的内容。也许,如上例所示,响应中包含指向代理以外其他服务器的绝对链接。

您可以使用 sub_filter 指令来定义要应用的重写:

sub_filter /blog/ /blog-staging/;sub_filter_once off;
复制代码


一个很常见的问题是 HTTP 压缩的使用。如果客户端发出信号表示可以接受压缩数据,而服务器随后压缩了响应,那么 NGINX 就无法检查和修改响应。最简单的方法是将 Accept-Encoding 请求头设置为空字符串 (""),从而将其从客户端请求中删除:

proxy_set_header Accept-Encoding "";
复制代码


完整示例

下面是一个负载均衡配置模板,它使用了本文提到的所有方法。NGINX Plus 具有的高级功能以橙色字体显示。


[编者按——以下配置已更新为使用 NGINX Plus API 对上游组进行实时活动监控和动态配置,取代了最初使用的单独模块。]

server {    listen 80;
location / { proxy_pass http://backend;
proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_redirect http://staging.example.com/ http://$host/;
# Rewrite the Host header to the value in the client request proxy_set_header Host $host;
# Replace any references inline to staging.example.com sub_filter http://staging.example.com/ /; sub_filter_once off; }
location /internal-health-check1 { internal; # Prevent external requests from matching this location block proxy_pass http://backend; health_check interval=2s fails=1 passes=5 uri=/test.php match=statusok; # Explicitly set request parameters; don't use runtime variables proxy_set_header Host www.example.com; } upstream backend { zone backend 64k; # Use NGINX Plus' shared memory least_conn; keepalive 20;
# Apply session persistence for this upstream group sticky cookie srv_id expires=1h domain=.example.com path=/servlet;
server webserver1 weight=1; server webserver2 weight=4; }
match statusok { # Used for /test.php health check status 200; header Content-Type = text/html; body ~ "Server[0-9]+ is alive";}
server { listen 8080; root /usr/share/nginx/html;
location = /api { api write=on; # Live activity monitoring and # dynamic configuration of upstream groups
allow 127.0.0.1; # permit access from localhost deny all; # deny access from everywhere else }}
复制代码


如欲试用 NGINX Plus 中所有出色的负载均衡功能,请点击此处阅读原文


NGINX 唯一中文官方社区 ,尽在 nginx.org.cn

更多 NGINX 相关的技术干货、互动问答、系列课程、活动资源: 开源社区官网 | 微信公众号

发布于: 2024-11-20阅读数: 3
用户头像

NGINX 唯一中文官方社区 2022-07-04 加入

NGINX 是全世界最流行的 Web 服务器,也可用于反向代理、负载均衡、API 网关等场景的开源软件,为全世界最繁忙的网站和应用提供支持。 微信:#NGINX开源社区

评论

发布
暂无评论
使用 NGINX 和 NGINX Plus 实现负载均衡(第 2 部分)_负载均衡_NGINX开源社区_InfoQ写作社区