通过Nginx代理下载超过1GB的文件失败

本文讨论了在Nginx代理下载大文件时可能出现的网络错误,原因在于默认的Buffer机制。解决方法包括调整proxy_max_temp_file_size大小,关闭Buffer或限制临时文件大小。同时提到了proxy_buffering的作用和注意事项。
摘要由CSDN通过智能技术生成

48f678dc04acae87ec7b8314bdb1a07a.png

项目场景:

浏览通过Nginx代理请求下载超过1GB文件

问题描述

前几天项目开发时发现,通过 Nginx 代理下载 超过1GB的大文件时,出现"网络错误",而在服务器上下载时却很正常。经确认排除嫌疑,最后发现是 Nginx Buffer 的锅。下面就来聊聊这个问题是怎么发生的。

原因分析:

Nginx Buffer 机制默认处于开启状态,其会根据 proxy_buffer_size 和 proxy_buffers 这两个参数控制写入内存的大小。

如果响应大于这个 buffer 大小,Nginx 会继续通过 proxy_max_temp_file_size 参数将响应其余部分写入到磁盘临时文件。

我遇到的问题:proxy_max_temp_file_size 默认为 1G,当客户端的网络比较慢时,临时文件很快就被写满。这时候后端的响应还会继续被接收到 socket 缓冲区,直到缓冲区被打满。

此时,Nginx 所在服务器通过滑动窗口 zero 0 告知后端服务器停止发送数据,直至触发了后端的 write 超时。

解决方案:

proxy_max_temp_file_size 2048m

* 调整 proxy_max_temp_file_size 大小

调大:让临时文件足够可以缓冲整个响应

调小:让整个链路上的数据流动起来,不要阻塞后端的 write 操作,进而触发后端的超时

* 关闭 Buffer:不推荐,会影响 Nginx 到后端的连接复用

71e634f0e3d8470a83ac677f23cbdc48.jpeg

 补充:

关于proxy_buffering:

proxy_buffering这个参数用来控制是否打开后端响应内容的缓冲区,如果这个设置为off,那么proxy_buffers和proxy_busy_buffers_size这两个指令将会失效。但是无论proxy_buffering是否开启,对proxy_buffer_size都是生效的。

proxy_buffering开启的情况下,nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端(边收边传,不是全部接收完再传给客户端)。临时文件由proxy_max_temp_file_size和proxy_temp_file_write_size这两个指令决定的。如果proxy_buffering关闭,nginx会立即把从后端收到的响应内容传送给客户端,每次取的大小为proxy_buffer_size的大小,这样效率肯定会比较低。

注:proxy_buffering启用时,要提防使用的代理缓冲区太大。这可能会吃掉你的内存,限制代理能够支持的最大并发连接数。

1d7f406d25d1b5a9aeef89e2ed4a0b94.jpeg

另,可以参考以下步骤

设置一,不限制临时文件大小

vim /etc/nginx/weijishu.conf

加入如下配置,

server {
    #...

    location / {
        #...
        proxy_max_temp_file_size 0;
        #...
    }
}

配置修改完成后,需要重载服务使配置生效,

systemctl reload nginx.service

注:缓冲区大小无限制,一直下载完整个文件

设置二,关闭代理响应缓存(可选)

vim /etc/nginx/nextcloud.cmdschool.org.conf

加入如下配置,

server {
    #...

    location / {
        #...
        proxy_buffering off;
        #...
    }
}

注:参数“proxy_buffering”设置为“off”则回应收到立刻同步传递到客户端
配置修改完成后,需要重载服务使配置生效,

systemctl reload nginx.service
通过Nginx代理做SFTP上传文件是一种比较常用的方案,可以提高安全性和灵活性。具体实现步骤如下: 1. 安装OpenSSH和Nginx: ```bash sudo apt-get install openssh-server nginx ``` 2. 配置OpenSSH: 在`/etc/ssh/sshd_config`文件中添加以下内容: ```text # 允许SFTP上传 Subsystem sftp /usr/lib/openssh/sftp-server Match group sftp ChrootDirectory /data/sftp/%u ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no PasswordAuthentication yes ``` 在这里,我们配置了SFTP的根目录为`/data/sftp/用户名`,限制了SFTP用户只能使用内置的sftp命令,不能使用ssh登录,同时开启了密码验证。 3. 配置Nginx: 在Nginx的配置文件中添加以下内容: ```nginx location /upload { auth_basic "Restricted"; # 开启基本认证 auth_basic_user_file /etc/nginx/.htpasswd; # 认证文件路径 proxy_pass sftp://127.0.0.1:22/; # 代理到本地的SFTP服务 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 配置上传文件大小限制 client_max_body_size 50M; } ``` 在这里,我们通过`proxy_pass`指定了SFTP上传的目标地址为本地的SFTP服务,同时开启了基本认证,并设置了上传文件的大小限制。 4. 创建SFTP用户和认证文件: ```bash sudo adduser sftpuser # 创建SFTP用户 sudo mkdir -p /data/sftp/sftpuser/upload # 创建上传目录 sudo chown sftpuser:sftp /data/sftp/sftpuser/upload # 设置目录权限 sudo htpasswd -c /etc/nginx/.htpasswd sftpuser # 创建认证文件 ``` 在这里,我们创建了一个名为`sftpuser`的SFTP用户,并创建了一个上传目录,设置了目录权限,并创建了一个认证文件。 通过以上步骤,我们就可以通过Nginx代理做SFTP上传文件了。用户可以通过SFTP客户端连接到Nginx,并上传文件到指定的上传目录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值