You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K8s部署中Nginx+Daphne突发连接时返回502问题排查

问题描述

Kubernetes环境中部署了包含两个容器的Pod:

  • 基于Daphne的Django应用,绑定Unix套接字(UDS)
  • Nginx反向代理,通过内存卷共享UDS与Django应用通信

日常运行正常,但在突发连接场景下(如Pod重启/缩容后,原Pod的5000个WebSocket连接分散到剩余9个Pod),会出现大量HTTP 502错误,提示上游/var/run/daphne.sock不可用,持续约20秒后恢复。改用TCP端口替代UDS后情况略有改善,但仍存在502错误。

当前场景:10个Pod承载50000个WebSocket连接,前端使用AWS ALB,目标组采用最少连接路由算法,每个Pod稳定承载约5000个连接。当Pod意外重启(OOM、节点故障)或缩容时,连接会临时转移到剩余Pod,期间出现502问题。

相关配置

Nginx配置

worker_processes 1;

user nobody nogroup;
error_log /var/log/nginx/error.log warn;
pid /tmp/nginx.pid;

events {
  worker_connections 16384;
}

http {
  include mime.types;
  # fallback in case we can't determine a type
  default_type application/octet-stream;
  sendfile on;
  access_log off;

  upstream ws_server {
    # fail_timeout=0 means we always retry an upstream even if it failed
    # to return a good HTTP response
    # for UNIX domain socket setups
    server unix:/var/run/daphne.sock fail_timeout=0;
  }

  server {
    listen 8443 ssl reuseport;
    ssl_certificate /etc/nginx/ssl/TLS_CRT;
    ssl_certificate_key /etc/nginx/ssl/TLS_KEY;
    ssl_client_certificate /etc/nginx/ssl/CA_CRT;
    ssl_protocols TLSv1.2 TLSv1.3;
    client_max_body_size 5M;
    client_body_buffer_size 1M;
    keepalive_timeout 65;

    location / {
      access_log /dev/stdout;

      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";

      proxy_redirect off;
      proxy_pass http://ws_server;
    }

    location /nginx_status {
      stub_status on;
    }
  }
}

Daphne启动命令

daphne app.asgi:application \
            -u /var/run/daphne.sock \
            --websocket_timeout 86400 \
            --websocket_connect_timeout 30

原因分析
  1. Daphne并发处理能力不足:每个Pod原本承载5000个WebSocket长连接,突发新增约555个连接时,Daphne默认的worker数量、连接队列长度不足以应对短时间内的连接重建请求,导致UDS/TCP端口暂时无法响应,Nginx返回502。
  2. Nginx上游健康检查缺失:当前仅设置fail_timeout=0,无主动健康检查机制。当Daphne暂时无法处理新连接时,Nginx仍持续转发请求,直到Daphne恢复,期间产生大量502。
  3. UDS的固有限制:相比TCP端口,UDS在高并发场景下更容易出现文件锁竞争、连接队列溢出问题,导致Nginx无法及时建立与Daphne的连接,这也是UDS场景下问题更严重的原因。
  4. ALB路由策略延迟:ALB的最少连接算法在Pod故障时,需要时间完成流量重分配,期间部分请求会被转发到暂时过载的Pod,加剧502错误。
缓解方案

Daphne层面优化

  • 调整启动参数提升并发:增加worker数量和监听队列长度,增强突发连接处理能力,示例命令:
    daphne app.asgi:application \
              -u /var/run/daphne.sock \
              --workers 4 \
              --backlog 8192 \
              --websocket_timeout 86400 \
              --websocket_connect_timeout 30
    
  • 设置连接上限:通过--max_connections参数限制单Pod最大连接数,避免超出承载极限,配合ALB流量分发实现连接均匀分配。

Nginx层面优化

  • 添加上游主动健康检查:配置Nginx主动检测Daphne状态,暂停转发请求直到其恢复,需确保Django提供/health/健康检查接口:
    upstream ws_server {
      server unix:/var/run/daphne.sock fail_timeout=0;
      # 健康检查配置
      check interval=2000 rise=1 fall=2 timeout=1000;
      check_http_send "HEAD /health/ HTTP/1.1\r\nHost: localhost\r\n\r\n";
      check_http_expect_alive http_2xx http_3xx;
    }
    
  • 调整连接参数:开启multi_accept让worker尽快接收新连接,同时合理设置代理超时参数,避免过早返回502:
    events {
      worker_connections 16384;
      multi_accept on;
    }
    
    http {
      # ... 其他配置
      proxy_connect_timeout 10s;
      proxy_send_timeout 30s;
      proxy_read_timeout 30s;
    }
    

Kubernetes与ALB层面优化

  • 优化Pod就绪探针:调整检查频率和阈值,确保Pod真正能处理连接时才被加入ALB目标组:
    readinessProbe:
      httpGet:
        path: /health/
        port: 8000 # 对应应用端口
      initialDelaySeconds: 5
      periodSeconds: 2
      failureThreshold: 2
    
  • 启用ALB连接 draining:在AWS ALB目标组中开启连接 draining,给Pod关闭前预留处理现有连接的时间,避免连接突然中断引发重建风暴。
  • 调整路由算法:将最少连接算法改为轮询,配合Pod连接数限制,让流量分发更均匀,减少单个Pod的突发压力。

内容的提问来源于stack exchange,提问作者dsnssc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:52:09