Gunicorn/Django/Nginx-502坏网关错误时上传文件超过100MB



我已经被这个错误困扰了一周。我对这件事完全不知所措。

我有一个React/Django网络应用程序,用户可以在其中上传音频文件(.WAV((通过reactDropzone(。React和Django完全分离为前端/和后端/文件夹,通过fetch((调用进行通信。出于某种原因,我可以上传小于100MB的文件,但如果我上传的文件更大,例如180MB,Nginx会出现以下错误:

2020/07/14 02:29:18 [error] 21023#21023: *71 upstream prematurely closed connection while reading response header from upstream, client: 50.***.***.***, server: api.example.com, request: "POST /api/upload_audio HTTP/1.1", upstream: "http://unix:/home/exampleuser/AudioUploadApp/AudioUploadApp.sock:/api/upload_audio", host: "api.example.com”, referrer: "https://example.com/profile/audio/record"

我的Gunicorn错误日志没有显示任何错误。我可以看到5个工人中的每一个都开始了,但没有WORKER超时错误或我能看到的任何错误。

我的guniocorn.service文件:

[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=exampleuser
Group=www-data
WorkingDirectory=/home/exampleuser/AudioUploadApp/Backend
ExecStart=/home/exampleuser/virtualenvs/uploadenv/bin/gunicorn --access-logfile "/tmp/gunicorn_access.log" --error-logfile "/tmp/gunicorn_error.log" --capture-output --workers 5 --worker-class=gevent --timeout=900 --bind unix/home/exampleuser/AudioUploadApp/AudioUploadApp.sock AudioUploadApp.wsgi:application --log-level=error
[Install]
WantedBy=multi-user.target
server {
server_name api.example.com;
location / {
include proxy_params;
proxy_pass http://unix:/home/exampleuser/AudioUploadApp/AudioUploadApp.sock;
client_max_body_size 200M;
}
location /static {
autoindex on;
alias /home/exampleuser/AudioUploadApp/Backend/static/;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
client_max_body_size 200M;
}
server {
server_name www.example.com example.com;
root /home/exampleuser/AudioUploadApp/build;
index index.html index.html;
location / {
try_files $uri /index.html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
client_max_body_size 200M;
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot

if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name www.example.com example.com;
listen 80;
return 404; # managed by Certbot
}server {
if ($host = api.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name api.example.com;
client_max_body_size 200M;
return 404; # managed by Certbot
}

我的Nginx代理参数:

proxy_set_header Host $http_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;
proxy_connect_timeout   900s;
proxy_send_timeout      900s;
proxy_read_timeout      900s;

我意识到我对Gunicorn和Nginx的超时太多了,但我所在的地方没有最好的上传速度,所以我只想确保上传速度导致的超时不是问题。

以下是我尝试过的,但没有成功:

  • 增加Gunicorn和Nginx的超时时间。有一次,我得到了一个504错误,这增加了超时时间
  • 工人人数增加
  • client_max_body_size 0;(不限制上传大小(
  • 增加React Dropzone组件上的maxFile变量
  • 升级AmazonEC2实例类型以获得更多CPU和RAM
  • 验证Django没有失败
    • 我在Django根据请求运行的第一个方法的开头就包含了print语句。据我所知,出于某种原因,请求并没有走那么远

重申一下,这似乎只发生在wav文件大小超过100MB的情况下。我已经成功地上传了80 MB的文件大小,但还没能上传150 MB的文件。

我已经做了大约一个星期了。我被卡住了。非常感谢您的帮助。如果我错过了任何有助于的信息,我可以提供更多信息

对此的修复是升级Gunicorn/Django/Nginx运行的EC2实例。我从t2.medium实例升级到R5.large实例。这起到了作用。然后,我从R5.large降到t2.large实例,它仍然有效。t2.medium和t2.large具有相同数量的虚拟CPU,但t2-lage具有两倍的内存量(4GiB对8GiB(。我声称已经这样做了,但当我收到的第一个错误是客户端太大时,我一定已经试过了。我通过更改Nginx中的client_max_body_size修复了这个错误。在那次改变之后,我得到了这个帖子的错误。我只是想在错误的地方升级硬件。

与我原来的帖子相比,我还做了以下更改,因为较大的数字似乎没有必要:

  • 古尼科恩的工人人数:从5人到3人
  • Gunicorn超时:从900到300
  • Nginx超时:从900s到300s

Gunicorn和Nginx可能会默认,但我还没有测试过。我住的地方上传速度很慢。

最新更新