$pipe 是 Nginx 1.1.4+ 内置只读变量,值为 p(流水线)或 .(非流水线),用于标识请求是否通过 HTTP pipelining 发送,仅在日志、if、map 等请求处理阶段有效,不可用于 rewrite 或 proxy_set_header。

$pipe 是 Nginx 内置的只读变量,用于标识当前请求是否通过 HTTP 流水线(HTTP pipelining)方式发送——即客户端在同一个 TCP 连接中连续发送多个请求而未等待前一个响应。该变量值为 p(pipelined)或 .(非流水线,即普通请求)。需注意:现代浏览器已普遍禁用 HTTP pipelining,因此该变量在常规 Web 场景中极少为 p,但在特定测试、代理链、IoT 设备或自定义 HTTP 客户端中仍有监控价值。
确认 $pipe 变量可用性与基础行为
Nginx 1.1.4+ 原生支持 $pipe,无需额外模块。它仅在请求处理阶段有效(如 log_format、if 判断、map 指令中),不可用于 rewrite 或 proxy_set_header 等指令中修改请求头。其取值严格由 Nginx 在解析请求行时判定:
- 若请求是连接中第二个及以上、且前序请求尚未响应完毕,则 $pipe = "p"
- 若为连接首请求,或连接启用 keepalive 但无流水线行为,则 $pipe = "."
- 该变量与 $connection、$request_length 等协同可辅助识别异常连接模式
在日志中记录并分析流水线请求
将 $pipe 加入 access_log 格式,是监控流水线行为最直接的方式:
log_format pipeline_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" $pipe $connection';
access_log /var/log/nginx/pipeline.log pipeline_log;
随后可通过日志分析工具(如 awk、goaccess 或 ELK)统计 p 出现频次、关联 IP、请求路径分布等。例如快速查看所有流水线请求:
awk '$12 == "p" {print}' /var/log/nginx/pipeline.log
结合 map 实现条件响应或限流
利用 map 指令将 $pipe 映射为布尔标记,可用于精细化控制:
map $pipe $is_pipelined {
default 0;
p 1;
}
<p>server {
location /api/ {</p><h1>拒绝流水线请求(适用于需强顺序保障的接口)</h1><pre class="brush:php;toolbar:false;"> if ($is_pipelined) {
return 403 "Pipelining not allowed";
}
proxy_pass https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e;
}}
⚠️ 注意:if 在 location 中有局限,更健壮的做法是用 limit_req 配合自定义 key:
limit_req_zone $binary_remote_addr$pipe zone=pipetest:10m rate=10r/s;
<p>location / {
limit_req zone=pipetest burst=5 nodelay;
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
}</p>
这样可对同一 IP 的流水线请求($pipe="p")和普通请求($pipe=".")区分限流。
调试与验证流水线行为
因主流浏览器不发起流水线请求,需用 curl 或专用工具构造测试:
- 使用
curl --http1.1并配合printf手动拼接请求(注意换行与空行) - 用
nc或openssl s_client直连 Nginx 端口发送原始 HTTP 请求 - 观察 access_log 中对应行的 $pipe 字段是否为
p,同时检查 $connection 是否复用(同一连接 ID 多次出现) - 确认 Nginx 配置中
keepalive_timeout> 0 且未设置disable_symlinks等干扰解析的指令
若始终无法触发 $pipe="p",需排查客户端是否真正发送了未等待响应的连续请求,以及 Nginx 是否启用了 HTTP/1.1 支持(默认开启)。











