插件窝 干货文章 高并发下,Nginx、uvicorn和gunicorn如何避免连接重置?

高并发下,Nginx、uvicorn和gunicorn如何避免连接重置?

timeout 连接 worker proxy 957    来源:    2025-03-11

在高并发场景下出现连接重置(Connection Reset)问题,通常与资源限制、超时配置、队列溢出或TCP内核参数有关。以下是针对Nginx、Uvicorn和Gunicorn的优化方案:


一、Nginx层优化

  1. 连接池与缓冲区

    worker_processes auto;  # 根据CPU核心数自动分配
    worker_rlimit_nofile 100000;  # 每个worker能打开的文件描述符上限
    
    events {
       worker_connections 20480;  # 单个worker最大连接数
       multi_accept on;          # 一次性接受所有新连接
    }
    
    http {
       proxy_buffer_size   128k;
       proxy_buffers   4 256k;
       proxy_busy_buffers_size   256k;
       proxy_temp_file_write_size 512k;
    }
    
  2. 超时与Keepalive

    upstream backend {
       server 127.0.0.1:8000;
       keepalive 100;  # 保持长连接池大小
    }
    
    server {
       keepalive_timeout  60s;    # 客户端长连接保持时间
       keepalive_requests 10000;  # 单个连接最大请求数
    
       location / {
           proxy_http_version 1.1;
           proxy_set_header Connection "";
           proxy_read_timeout 300s;  # 关键:增加后端响应超时
           proxy_send_timeout 300s;
           proxy_connect_timeout 75s;
       }
    }
    

二、Gunicorn/Uvicorn优化

  1. Worker配置

    # 使用Uvicorn Workers(适合异步框架如FastAPI)
    gunicorn -w $((2 * $(nproc) + 1)) --worker-class uvicorn.workers.UvicornWorker --timeout 120 app:app
    
    # 同步Worker配置(适合Django等同步框架)
    gunicorn -w $((2 * $(nproc) + 1)) --threads 4 --max-requests 1000 --timeout 120 app:app
    
    • -w: Worker数量 = 2*CPU核心 + 1
    • --max-requests: 防止内存泄漏,定期重启Worker
    • --timeout: 请求处理超时时间需大于Nginx的proxy_read_timeout
  2. 异步处理优化

    # 在ASGI应用(如FastAPI)中启用异步路由
    @app.get("/io_task")
    async def io_bound_task():
       await some_async_io()
    

三、操作系统级优化

  1. TCP内核参数

    # 调整临时端口范围
    echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range
    
    # 加快TIME_WAIT回收
    echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
    echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
    echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
    
    # 增加最大文件描述符
    ulimit -n 100000
    sysctl -w fs.file-max=100000
    
  2. SYN洪水防护

    sysctl -w net.ipv4.tcp_max_syn_backlog=65536
    sysctl -w net.core.somaxconn=65536
    

四、典型问题排查

  1. 监控指标

    • netstat -s | grep -E 'reset|timeout':检查RST包数量
    • ss -s:查看当前连接状态分布
    • Nginx错误日志:/var/log/nginx/error.log 搜索 104: Connection reset by peer
  2. 常见原因

    • 后端服务处理超时(需增加proxy_read_timeout和Gunicorn超时)
    • 客户端提前关闭连接(需检查客户端稳定性)
    • 操作系统端口耗尽(优化ip_local_port_range

五、压力测试验证

使用wrkab模拟高并发:

wrk -t12 -c4000 -d30s http://your_service

观察是否出现Socket errors: connect 0, read 0, write 0, timeout 0, reset X


通过上述多层级优化,可显著降低高并发下的连接重置问题。建议逐步调整参数并配合监控工具(如Prometheus+Grafana)验证效果。