我有一个Nginx + uWSGI + Flask设置,实现了一个Web应用程序,用户可以在其中下载大文件(大约3GB)。问题是,有时在使用Firefox时下载不会启动(下载管理器栏会来回移动)。 Chrome不会发生此问题。
在uWSGI日志中,显示以下消息:
uwsgi_response_write_body_do() TIMEOUT !!!
OSError: write error
我尝试在Nginx配置文件中设置uwsgi_max_temp_file_size 0;
,但这不能解决我的问题。
这里是所有相关代码。
烧瓶代码
def generate():
# create and return your data in small parts here
with open(os.path.abspath(app.root_path)+server_path, 'rb') as f:
while True:
read_data = f.read(1024)
if not read_data:
break # done
yield read_data
response = Response(stream_with_context(generate()), mimetype=mimetype)
response.headers['Content-Disposition'] = 'attachment; filename={}'.format(file_basename)
response.headers['Content-Length'] = os.path.getsize(os.path.abspath(app.root_path)+server_path)
return response
uWSGI
[uwsgi]
virtualenv = /home/simone/Documents/LabDash/venv
mount = /home/simone/Documents/LabDash=LabDash:app
; tell uWSGI to rewrite PATH_INFO and SCRIPT_NAME according to mount-points
manage-script-name = true
master = true
processes = 5
socket = LabDash.sock
chmod-socket = 660
vacuum = true
die-on-term = true
; to remove in production, just used for debugging
catch-exceptions= true
; auto-reload feature
touch-reload = /home/simone/Documents/LabDash/app/routes.py
Nginx
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log debug;
##
# Gzip Settings
##
gzip on;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
server {
listen 4000;
client_max_body_size 10G;
server_name testdomain www.testdomain;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/simone/Documents/LabDash/LabDash.sock;
}
}
在Nginx错误日志中:
writev() failed (104: Connection reset by peer) while reading upstream
如果使用Flask的send_file
代替流式传输,则问题仍然存在,并且在Nginx的日志中,我有:
epoll_wait() reported that client prematurely closed connection, so upstream connection is closed too