在典型的反向代理流程中,当客户端请求到达Nginx服务器后,Nginx会将其转发至上游服务端。本文将深入探讨Nginx如何接收并处理来自上游服务器的HTTP响应,涵盖响应头部和响应包体两个关键阶段。
处理流程回顾:Nginx接收上游响应分为两个阶段,一是接收并处理响应头部(Header),二是处理响应包体(Body)。响应的接收由Nginx的upstream框架负责,而响应头部的具体处理则由如proxy、gRPC、CGI、UWSGI等反向代理模块完成。
此外,响应内容在发送给客户端前,还必须经过Nginx过滤模块(如header_filter)的处理,这为添加、修改或删除响应头信息提供了可能。
关键指令参数详解
1. 接收与处理响应头部
-
proxy_buffer_size
此指令用于设置读取上游响应头部时使用的缓冲区大小。默认值为4k或8k,取决于平台。若上游返回的响应头超过此大小,将无法正确处理,并在错误日志中记录“upstream sent too big header”。
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location
-
proxy_ignore_headers
用于忽略(禁用)上游响应头中的特定功能字段,例如X-Accel-Redirect、X-Accel-Limit-Rate等。这在需要防止上游通过特定头部控制Nginx行为时非常有用。
Syntax: proxy_ignore_headers field ...;
Default: —;
Context: http, server, location
-
proxy_hide_header
用于隐藏上游响应中的某些字段,不传递给客户端。默认情况下,Nginx不会传递Date、Server、X-Pad和X-Accel-等头部。
Syntax: proxy_hide_header field;
Default: —;
Context: http, server, location
-
proxy_pass_header
与proxy_hide_header相反,用于允许传递默认被禁用的头部字段给客户端。
Syntax: proxy_pass_header field;
Default: —;
Context: http, server, location
-
proxy_cookie_domain / proxy_cookie_path
分别用于重写上游响应Set-Cookie头部中的domain和path值,常用于跨域资源共享(CORS)场景。
# 示例
proxy_cookie_domain localhost example.org;
proxy_cookie_path /two/ /;
-
proxy_redirect
用于重写上游响应中的Location、Refresh等重定向头部字段。
# 示例:将上游的重定向地址映射为对外的地址
proxy_redirect http://localhost:8000/two/ http://weiyigeek.top/one/;
2. 接收与处理响应包体
-
proxy_buffering
控制是否先完整接收上游的响应包体再转发给客户端。默认为on(开启缓冲)。设为off时,响应将实时流式转发给客户端,适用于流媒体或大文件下载场景。上游的X-Accel-Buffering头部可覆盖此设置。
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location
-
proxy_buffers
设置用于缓存上游响应包体的内存缓冲区数量和大小。默认是8个,每个4k或8k。若响应体超出内存缓冲区总量,超出部分会写入临时文件。
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location
-
proxy_max_temp_file_size / proxy_temp_file_write_size / proxy_temp_path
这三个指令共同控制磁盘缓存:
-
proxy_busy_buffers_size
此指令设置在响应尚未完全接收时,可以用于向客户端发送数据的“忙碌缓冲区”总大小。实现“边收边发”,提升用户体验。该值不能超过proxy_buffers的总大小。
Syntax: proxy_busy_buffers_size size;
Default: proxy_busy_buffers_size 8k|16k;
Context: http, server, location
3. 响应超时与速率控制
-
proxy_read_timeout
设置从上游读取响应的超时时间。超时后连接关闭。
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
-
proxy_limit_rate
限制从上游服务器读取数据的速率(字节/秒)。仅当proxy_buffering开启时生效。
Syntax: proxy_limit_rate rate;
Default: proxy_limit_rate 0;
Context: http, server, location
4. 响应包体持久化
-
proxy_store / proxy_store_access
允许将上游的响应内容作为静态文件保存到磁盘。proxy_store_access用于设置保存文件的访问权限。
Syntax: proxy_store on | off | string;
Default: proxy_store off;
Context: http, server, location
Syntax: proxy_store_access users:permissions ...;
Default: proxy_store_access user:rw;
Context: http, server, location
实践示例
示例1:处理上游响应头部
目标:演示如何通过Nginx过滤、透传或忽略上游服务返回的特定响应头。
步骤:
- 搭建上游服务:在一台服务器(如10.20.172.213)上配置一个监听8010端口的服务,返回自定义头部。
location / {
add_header X-Custom-Name 'weiyigeek';
add_header X-Accel-Limit-Rate 10; # 控制Nginx读取速度为10 bytes/s
}
-
配置Nginx反向代理:在另一台Nginx服务器(代理服务器)上进行如下配置。
upstream backend_server {
server 10.20.172.213:8010;
keepalive 10;
}
server {
listen 80;
server_name test.weiyigeek.top;
location / {
proxy_pass http://backend_server;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 隐藏上游的X-Custom-Name头
proxy_hide_header X-Custom-Name;
# 允许透传上游的Server头(默认被隐藏)
proxy_pass_header Server;
# 实验:分别注释/取消注释以下两行,观察X-Accel-Limit-Rate头部的效果
proxy_pass_header X-Accel-Limit-Rate;
# proxy_ignore_headers X-Accel-Limit-Rate;
}
}
- 测试验证:
- 当启用
proxy_pass_header X-Accel-Limit-Rate; 时,该头部会传递给客户端,并实际生效(下载速度极慢)。
- 当启用
proxy_ignore_headers X-Accel-Limit-Rate; 时,Nginx会忽略该头部的限速指令,下载速度恢复正常。

示例2:持久化存储请求与响应
目标:将客户端请求体和上游响应体都持久化保存到磁盘文件。
步骤:
- 准备本地测试服务:在代理服务器本地创建两个测试服务(8011和8012端口),模拟上游服务器。
- 配置负载均衡:定义
upstream组,包含这两个服务。
upstream backend {
zone backend_zone 64k;
server 127.0.0.1:8011 weight=2;
server 127.0.0.1:8012;
}
-
配置反向代理与持久化:创建代理服务,并启用客户端请求体和服务端响应体的持久化存储。
server {
listen 80;
server_name test.weiyigeek.top;
# 持久化客户端请求体到文件
client_body_in_file_only on;
client_body_temp_path /var/tmp/nginx/client_temp 1 2;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 持久化上游响应体到文件
root /var/tmp/nginx/proxy_store;
proxy_store on;
proxy_store_access user:rw group:rw all:r;
# 配置响应缓冲
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
proxy_temp_path /var/tmp/nginx/proxy_temp 1 2;
}
}
- 测试验证:使用
curl发送POST请求,检查文件是否生成。
$ curl -X POST -d 'Client Request 1' http://test.weiyigeek.top/index.txt
$ tree /var/tmp/nginx/
可以看到在/var/tmp/nginx/client_temp和/var/tmp/nginx/proxy_store目录下分别生成了对应的请求体和响应体文件。

总结
通过合理配置上述指令,可以精细控制Nginx在处理上游服务器响应时的行为,无论是头部的过滤重写、包体的缓冲与流式传输,还是响应内容的持久化存储,都是构建高效、稳定反向代理服务的关键环节。理解Nginx与上游服务间的HTTP交互细节,有助于优化性能并满足特定的业务需求。
|