Rails + thin:无法下载大文件

时间:2015-01-20 12:26:01

标签: ruby-on-rails thin

我有一个rails应用程序,用户可以在其中管理大文件(目前最多15 GB)。他们还可以下载存储的文件。

一切都适用于文件< 510 MB。但是对于> 510 MB,下载在522,256 KB(510 MB)之后停止。

我认为thin会产生这个问题。当我使用瘦启动我的开发服务器时,我无法下载完整的文件。当我使用webrick启动开发服务器时,一切正常。

我使用top来比较RAM / CPU行为,但server,thin和webrick的行为方式相同。在开发过程中,服务器都将完整的文件读入RAM,然后将其发送给用户/客户端。

我尝试更改send_file的一些选项,例如streambuffer_size。我还手动设置了length。但同样,我无法使用瘦文件下载完整的文件。

我可以使用Firefox,Chrome和curl重现此行为。

问题是我的高效rails应用程序在nginx代理后面使用4个瘦服务器。目前,我不能使用独角兽或乘客。

在开发过程中,我使用thin 1.6.3rails 4.1.8ruby 2.1.2

def download
  file_path = '/tmp/big_file.tar.gz' # 5 GB
  send_file(file_path, buffer_size: 4096, stream: true)
end

1 个答案:

答案 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的斗争。

相关问题