HTTP 协议反向代理中与上游服务端建立连接处理
本小节将重点讲解 Nginx 在与上游服务建立连接时的一系列关键指令参数配置,包括超时控制、异常处理、连接复用等,这些配置对于构建稳定高效的反向代理架构至关重要。
指令参数
1. 向上游服务器建立连接以及发送请求的超时时间控制
proxy_connect_timeout 设置与上游服务建立连接的超时时间,缺省值 60s。如果在此时间内无法完成连接,则返回 502(Bad Gateway)错误。特别注意:超时设置通常不能超过75秒。
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
proxy_send_timeout 设置向上游服务发送请求的超时时间,缺省值 60s。如果在此时间内无法完成数据传输,则连接将关闭,并返回 504(Gateway Time-out)错误。特别注意:超时仅在两个连续的写操作之间设置,而不是为整个请求的传输设置。
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
2. 当上游服务器建立连接异常时错误处理与故障转移
proxy_next_upstream 指令用于控制当上游服务出现错误时,是否尝试选择另一个上游服务器进行请求转发,即故障转移机制。缺省值为 error 以及 timeout。特别注意:其生效的前提是 Nginx 尚未向客户端发送任何响应字节。
Syntax: proxy_next_upstream error | timeout | denied | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off ...;
Default: proxy_next_upstream error timeout;
Context: http, server, location
# 参数说明:
# error 当与上游建立连接、发送请求或读取响应过程中发生网络层面错误(如 TCP/IP 层错误)时触发重选;
# timeout 与上游建立连接超时(connect timeout)、读取超时(read timeout)等场景下触发重选;
# denied 服务器拒绝连接时;
# invalid_header 当上游服务返回的 HTTP header 不合法时触发;
# http_xxx 服务器返回了指定的HTTP错误代码时;
# non_idempotent 允许对非幂等方法(如 POST、PATCH)的请求进行重试;
# off 禁止故障转移功能。
proxy_next_upstream_timeout 指令用于限制故障转移尝试的总时间,若为 0 则表示不限制。
proxy_next_upstream_tries 指令用于限制故障转移的尝试次数,若为 0 则表示不限制重试次数。
Syntax: proxy_next_upstream_timeout time;
Default: proxy_next_upstream_timeout 0;
Context:http, server, location
Syntax: proxy_next_upstream_tries number;
Default: proxy_next_upstream_tries 0;
Context: http, server, location
proxy_intercept_errors 指令用于决定是否拦截来自上游的错误响应(状态码 ≥ 300)并使用 Nginx 的 error_page 指令进行处理。缺省值 off 表示将上游服务的错误原样返回给客户端。
Syntax: proxy_intercept_errors on | off;
Default: proxy_intercept_errors off;
Context: http, server, location
在分布式部署场景中,合理配置上游服务器连接异常处理与重选机制,对于保障服务的性能与稳定性是非常必要的。
3. 为上游服务器连接启用 Keepalive 机制
Keepalive 机制分为 TCP keepalive 与 HTTP keepalive 两部分。
3.1 TCP keepalive 机制
proxy_socket_keepalive 用于控制是否在连接上游服务器时启用 TCP 层的 keepalive。设置为 on 会打开 SO_KEEPALIVE 套接字选项,有助于检测并关闭失效的长连接。
Syntax: proxy_socket_keepalive on | off;
Default: proxy_socket_keepalive off;
Context: http, server, location
This directive appeared in version 1.15.6.
3.2 HTTP keepalive 机制
此机制通常在 upstream 块中配置,用于复用 HTTP 连接,减少 TCP 握手开销。相关指令包括:
keepalive connections: 设置每个 worker 进程维护的空闲连接数上限。
keepalive_requests number: 设置单个 keepalive 连接最多处理的请求数。
keepalive_timeout timeout: 设置空闲连接保持打开的最长时间。
4. 为上游服务器请求连接指定本地出口 IP 地址
proxy_bind 指令用于指定发起代理连接的本地源 IP 地址。这对于多IP主机或需要 IP 透传的场景非常有用。
Syntax: proxy_bind address [transparent] | off;
Default: —
Context: http, server, location
# 参数说明:
# transparent 参数允许从非本地IP地址(例如客户端的真实IP)发起连接,实现透明代理。
在实践中,使用 proxy_bind 指定源IP后,务必确保上游返回的数据包能正确路由回 Nginx 服务器,否则连接会中断。
5. 当客户端断开后的与上游服务器的连接控制
proxy_ignore_client_abort 指令用于控制当客户端提前关闭连接时,是否继续维持与上游服务器的连接。默认关闭(off),Nginx 会立即终止上游连接。
Syntax: proxy_ignore_client_abort on | off;
Default: proxy_ignore_client_abort off;
Context: http, server, location
示例演示
示例1. 在 Nginx 实现反向代理时,配置连接异常自动切换节点以及自定义错误页面。
-
步骤 01. 搭建上游服务
在 IP 为 10.20.172.213 的主机上,使用 OpenResty 搭建两个简单的上游服务:
http {
server {
listen 8010;
# 返回 200 响应码
return 200 "Response 200, this is upstream server on port $server_addr:$server_port\n";
}
server {
listen 8011;
# 模拟异常,返回 500 错误响应码
return 500 "Response 500, this is upstream server on port $server_addr:$server_port\n";
}
}
-
步骤 02. 定义上游服务器组
在 Nginx 代理服务器(10.20.172.214)上创建 backend_server.conf:
upstream backend_server {
zone backend_zone 64k;
server 10.20.172.213:8010;
server 10.20.172.213:8011;
keepalive 10;
keepalive_timeout 60s;
}
-
步骤 03. 配置反向代理服务器
创建 proxy_server.conf,包含三个 location 用于测试不同场景:
# 创建自定义错误页面
echo "error_page HTTP 500 Internal Server Error" > /usr/local/nginx/html/error_500.txt
server {
listen 80;
server_name test.weiyigeek.top;
# 场景1:关闭故障转移,观察默认行为
location / {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_next_upstream off; # 关闭自动切换
}
# 场景2:启用故障转移,模拟连接超时和500错误时切换
location /error {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_connect_timeout 1s; # 模拟连接超时
proxy_next_upstream error timeout invalid_header http_500; # 启用故障转移条件
}
# 场景3:拦截上游错误,返回自定义页面
location /intercept {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_intercept_errors on; # 启用错误拦截
proxy_next_upstream off;
}
# 定义500错误码的默认页面路径
error_page 500 /error_500.txt;
location =/error_500.txt {
root html/;
}
}
- **步骤 04. 验证测试**
- **验证1:访问 `/` 路径**(关闭故障转移)
当上游 8011 端口服务返回 500 时,客户端直接收到 500 响应。当 8011 端口不可用时,Nginx 返回 502 Bad Gateway。
- **验证2:访问 `/error` 路径**(启用故障转移)
当连接 8011 端口超时或收到 500 错误时,请求会自动切换到正常的 8010 端口节点,始终返回 200 响应。
- **验证3:访问 `/intercept` 路径**(启用错误拦截)
当请求到达返回 500 错误的 8011 端口时,Nginx 会拦截该错误,并返回自定义的 `error_500.txt` 页面内容,而不是上游的原始错误体。
通过以上实践,可以有效处理上游服务故障和不良响应,利用 Nginx 的[反向代理与负载均衡能力](https://yunpan.plus/f/23-1)增强后端系统的健壮性和透明度。下一节将讲解 Nginx 如何接收并处理来自上游的 HTTP 响应。
---