Nginx长连接与Pipeline详解
1. Keepalive(长连接)
概念
HTTP/1.1默认使用持久连接,允许在单个TCP连接上发送多个HTTP请求/响应,减少建立/关闭连接的开销。
Nginx配置
http {
# 客户端到Nginx的长连接
keepalive_timeout 65; # 连接保持时间(秒)
keepalive_requests 100; # 单个连接最大请求数
# Nginx到上游服务器的长连接
upstream backend {
server 10.0.0.1:8080;
# 连接池配置
keepalive 32; # 每个worker进程连接池大小
keepalive_timeout 60s; # 连接保持时间
keepalive_requests 100; # 单连接最大请求数
}
server {
location /api/ {
proxy_pass http://backend;
# 启用上游长连接
proxy_http_version 1.1;
proxy_set_header Connection "";
# 长连接超时设置
proxy_connect_timeout 75s;
proxy_read_timeout 300s;
}
}
}
配置说明
客户端侧keepalive:
keepalive_timeout:空闲连接保持时间
keepalive_requests:单个连接处理请求上限,达到后强制关闭
上游连接池:
# 完整配置示例
upstream backend {
server backend1.example.com;
server backend2.example.com;
# 每个worker保持的最大空闲连接数
keepalive 100;
# 连接在连接池中保持的最长时间
keepalive_timeout 60s;
# 单个连接处理的最大请求数
keepalive_requests 1000;
}
2. Pipeline(管线化)
概念
允许客户端在收到响应前发送多个请求,减少RTT(往返时间)。
工作机制
客户端发送: 请求1 → 请求2 → 请求3
服务器响应: 响应1 → 响应2 → 响应3
(按请求顺序返回)
Nginx对Pipeline的支持
- 默认支持HTTP/1.1 pipeline
- 自动处理请求排队和响应顺序
- 上游请求默认不支持pipeline
配置示例
http {
# 优化pipeline性能
client_header_timeout 15s; # 请求头读取超时
client_body_timeout 15s; # 请求体读取超时
send_timeout 10s; # 响应发送超时
# 缓冲区设置(影响pipeline处理)
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# 限制pipeline请求数量(防止DoS)
limit_req_zone $binary_remote_addr zone=pipeline:10m rate=100r/s;
server {
location / {
limit_req zone=pipeline burst=50;
# ... 其他配置
}
}
}
3. Keepalive + Pipeline结合使用
最佳实践配置
events {
worker_connections 10240; # 需要足够连接数
use epoll; # Linux高性能事件模型
}
http {
# 客户端连接优化
keepalive_timeout 75s;
keepalive_requests 1000;
# TCP优化(Linux)
tcp_nodelay on; # 禁用Nagle算法
tcp_nopush on; # 启用TCP_CORK
# 缓冲区优化
client_body_buffer_size 128k;
client_max_body_size 10m;
upstream app_servers {
least_conn; # 负载均衡算法
server 10.0.0.1:8080 weight=3;
server 10.0.0.2:8080 weight=2;
# 连接池配置
keepalive 50;
keepalive_timeout 60s;
keepalive_requests 500;
}
server {
listen 80 reuseport; # Linux 3.9+ 端口复用
location /api/ {
proxy_pass http://app_servers;
# 启用HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Upgrade $http_upgrade;
# 超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲区
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# 健康检查
proxy_next_upstream error timeout http_502;
}
# 静态文件优化
location ~* \.(jpg|png|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
keepalive_timeout 300s;
}
}
}
4. 监控与调试
状态监控
# 开启状态模块
server {
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
location /upstream_status {
proxy_pass http://app_servers/status;
}
}
日志记录连接信息
log_format extended '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'upstream_addr=$upstream_addr '
'upstream_connect_time=$upstream_connect_time '
'upstream_header_time=$upstream_header_time '
'upstream_response_time=$upstream_response_time '
'connection=$connection '
'connection_requests=$connection_requests';
access_log /var/log/nginx/access.log extended;
5. 性能调优建议
Linux内核参数优化
# /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0 # 不建议开启
net.ipv4.tcp_max_tw_buckets = 20000
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15
# 临时生效
sysctl -p
压力测试
# 使用wrk测试keepalive性能
wrk -t4 -c100 -d30s --timeout 2s --latency http://example.com
# 测试pipeline
wrk -t4 -c100 -d30s --timeout 2s --latency \
-s pipeline.lua -- 16 http://example.com
# pipeline.lua内容
init = function(args)
local r = {}
for i=1, tonumber(args[1]) do
r[i] = wrk.format(nil, "/")
end
req = table.concat(r)
end
request = function()
return req
end
6. 注意事项
连接池大小计算:
每个worker连接数 = keepalive * upstream服务器数量
总连接数 = worker_processes * 每个worker连接数
内存占用:每个TCP连接约占用3-10KB内存
超时陷阱:
keepalive_timeout 必须大于后端服务超时时间
- 注意
proxy_read_timeout设置
HTTP/2优势:
listen 443 ssl http2; # HTTP/2天然支持多路复用
监控指标:
accepts:接受的客户端连接数
handled:成功处理的连接数
requests:处理的请求总数
Reading/Writing/Waiting:连接状态
7. 故障排查
# 调试日志
error_log /var/log/nginx/error.log debug;
# 查看连接状态
ss -tan | grep :80 | awk '{print $1}' | sort | uniq -c
# 监控连接数
watch -n1 "netstat -an | grep :80 | awk '/^tcp/ {++S[\$NF]} END {for(a in S) print a, S[a]}'"
通过合理配置keepalive和pipeline,可以显著提升HTTP性能,特别是在高并发、延迟敏感的场景下。建议根据实际流量模式和硬件资源进行调整优化。