我有一个rails应用程序,用户可以在其中管理大文件(目前最多15 GB)。他们还可以下载存储的文件。
一切都适用于文件< 510 MB。但是对于> 510 MB,下载在522,256 KB(510 MB)之后停止。
我认为thin
会产生这个问题。当我使用瘦启动我的开发服务器时,我无法下载完整的文件。当我使用webrick启动开发服务器时,一切正常。
我使用top
来比较RAM / CPU行为,但server,thin和webrick的行为方式相同。在开发过程中,服务器都将完整的文件读入RAM,然后将其发送给用户/客户端。
我尝试更改send_file
的一些选项,例如stream
或buffer_size
。我还手动设置了length
。但同样,我无法使用瘦文件下载完整的文件。
我可以使用Firefox,Chrome和curl重现此行为。
问题是我的高效rails应用程序在nginx代理后面使用4个瘦服务器。目前,我不能使用独角兽或乘客。
在开发过程中,我使用thin 1.6.3
,rails 4.1.8
,ruby 2.1.2
。
def download file_path = '/tmp/big_file.tar.gz' # 5 GB send_file(file_path, buffer_size: 4096, stream: true) end
答案 0 :(得分:1)
如果您使用send_file
,最好使用前端代理来解除提供文件的责任。你说你在生产中使用nginx,所以:
在production.rb
文件中,取消注释config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
。
您还必须更改nginx配置以容纳Rack::Sendfile
。其文档位于here。更改相当于添加:
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
proxy_set_header X-Accel-Mapping /=/files/; # or something similar that doesn't interfere with your routes
到您现有的位置区块,并添加一个额外的location
块,用于处理您添加的X-Accel-Mapping
。新的位置块可能如下所示:
location ~ /files(.*) {
internal;
alias $1;
}
当你ssh到你的生产服务器和curl -I
瘦服务器(不 nginx)并看到X-Accel-Redirect
标题时,你会知道它正常工作。如果不发送文件内容,curl
(无-I
)直接发送到thin
服务器。
你可以看到我最近与nginx和send_file here的斗争。