Nginx反向代理Flask应用报504错误,Docker端口映射正常
问题分析与修复方案
核心问题定位
从抓包日志和配置细节来看,导致504 Gateway Time-out的根源是:
- Nginx配置中强制为所有请求添加了WebSocket专属的
Connection: upgrade和Upgrade请求头,而GeventWebSocketWorker在处理普通HTTP POST请求时,会因为这些不符合HTTP规范的头出现处理延迟,最终触发Nginx的proxy_read_timeout(配置的120秒)。Nginx关闭连接后Flask才完成请求处理,此时响应已无法被转发。 - 直接访问Flask容器时没有这些额外头,因此Gunicorn能正常处理请求,无延迟。
修复方案
1. 修正Nginx的WebSocket头配置
修改Nginx的server配置,仅对真正的WebSocket请求添加升级头,避免干扰普通HTTP请求:
server { listen 80; server_name 52.195.89.113; location / { proxy_pass http://sharing_sketch_20240711:8002; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 仅当请求为WebSocket时,添加升级相关头 if ($http_upgrade = "websocket") { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # 保持原有超时配置,可根据业务调整 proxy_connect_timeout 120s; proxy_read_timeout 120s; proxy_send_timeout 120s; proxy_cache off; } }
修改后重启Nginx容器:
docker restart nginx-https
2. 优化Gunicorn Worker配置(可选)
当前仅使用1个GeventWebSocketWorker,对于混合HTTP+WebSocket的场景,可适当增加worker数量提升并发处理能力:
修改run_server.sh:
#!/bin/sh gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 2 --threads 5 -b 0.0.0.0:8002 PSS.wsgi:application --access-logfile ./access.log --error-logfile ./error.log
重启Flask容器:
docker restart sharing_sketch_20240711
3. 升级Docker网络配置(可选)
Docker Compose的links指令已过时,建议使用自定义桥接网络替代,提升容器间通信的稳定性:
修改docker-compose.yml:
services: nginx: container_name: nginx-https image: nginx:latest restart: always ports: - "80:80" - "443:443" networks: - app-network volumes: - ./certbot/conf:/etc/letsencrypt - ./conf.d:/etc/nginx/conf.d/:rw - ./certbot/www/:/var/www/certbot/:ro sketch: ports: - "8002:8002" container_name: sharing_sketch_20240711 environment: - PYTHONUNBUFFERED=1 image: pss_websocket networks: - app-network networks: app-network: driver: bridge
重新部署容器:
docker-compose up -d
验证步骤
- 通过Nginx访问登录页面(无端口),提交登录请求,检查是否返回正常响应
- 查看Flask的
access.log,确认请求处理时间是否在Nginx超时时间内 - 再次抓包验证,确认普通POST请求不会被添加WebSocket升级头
内容的提问来源于stack exchange,提问作者bizara
相关产品推荐
相关产品推荐

