如何用Nginx替换提供单静态文件下载接口的Python Flask应用
用Nginx替代Flask提供大文件下载服务
背景
之前用Flask写了一个小型Web服务,供用户下载单个静态文件,代码如下:
import flask app = flask.Flask(__name__) @app.route('/') def index(): return 'go to /file.txt to download file' @app.route('/file.txt') def file_txt(): with open('/static/file.txt', 'r') as ifile: data = ifile.read() return data if __name__ == '__main__': app.run(debug=True, host='127.0.0.1', port=80)
现在需要提供一个约15GB的大文件下载,但服务器仅4GB内存,Flask会将整个文件读入内存,显然不可行。因此计划用Nginx替代Flask,已完成Nginx安装,域名已指向服务器IPv4地址,待下载文件路径为/static/file.txt,尝试的Nginx配置如下:
# cat nginx.conf user www-data; worker_processes auto; pid /run/nginx.pid; error_log /var/log/nginx/error.log; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; # multi_accept on; } http { sendfile on; tcp_nopush on; 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_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; access_log /var/log/nginx/access.log; gzip on; # gzip_vary on; # gzip_proxied any; # gzip_comp_level 6; # gzip_buffers 16 8k; # gzip_http_version 1.1; # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; server { listen 80; listen [::]:80; server_name my-server-domain-name.example; location /download/ { root /static; add_header X-debug-message "test" always; try_files /file.txt =404; } } include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
注:/etc/nginx/sites-enabled目录下无符号链接。
正确配置方案
现有配置存在路径匹配问题,且需要针对大文件下载添加优化配置,确保Nginx不会占用过多内存:
1. 修正服务器块配置
根据你想要的访问路径,选择以下两种配置方式之一:
方式一:通过/file.txt直接访问(与原Flask服务路径一致)
server { listen 80; listen [::]:80; server_name my-server-domain-name.example; # 根路径提示 location / { return 200 'go to /file.txt to download file'; add_header Content-Type text/plain; } # 大文件下载路径 location /file.txt { # 指定文件所在目录,Nginx会拼接为 /static/file.txt root /static; # 启用sendfile零拷贝,减少内存占用 sendfile on; tcp_nopush on; tcp_nodelay on; # 支持断点续传 add_header Accept-Ranges bytes; # 禁止gzip压缩大文件,避免额外CPU/内存开销 gzip off; } }
方式二:通过/download/file.txt访问
若希望保留/download/前缀,调整root和try_files的用法:
server { listen 80; listen [::]:80; server_name my-server-domain-name.example; location / { return 200 'go to /download/file.txt to download file'; add_header Content-Type text/plain; } location /download/ { # root指向根目录,Nginx会拼接为 /static/file.txt root /; try_files $uri /static/file.txt =404; sendfile on; tcp_nopush on; tcp_nodelay on; add_header Accept-Ranges bytes; gzip off; } }
2. 全局配置优化(可选)
在http块中添加或确认以下配置,进一步优化大文件传输:
http { # 保留原有配置... # 禁用请求体大小限制,调整客户端缓冲区 client_max_body_size 0; client_body_buffer_size 128k; # 调整输出缓冲区,适配大文件 output_buffers 1 32k; postpone_output 1460; # 保留原有server块... }
3. 权限检查
确保Nginx运行用户www-data对目标文件有读取权限:
chmod o+r /static/file.txt
4. 验证配置并重启Nginx
nginx -t systemctl restart nginx
配置完成后,Nginx会通过sendfile零拷贝机制直接从磁盘分块读取文件发送,不会将整个大文件加载到内存,适配4GB内存的服务器需求。
内容的提问来源于stack exchange,提问作者user2138149
相关产品推荐
相关产品推荐

