欢迎光临中国护送网
详情描述

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性能,特别是在高并发、延迟敏感的场景下。建议根据实际流量模式和硬件资源进行调整优化。