Ruby on rails 使用回形针加速S3上传
我用回形针上传S3中的图像。 但是我注意到这个上传速度非常慢。我认为,因为在完成提交之前,文件必须经过我的服务器,进行处理并发送到S3服务器 有什么方法可以加速这一过程吗Ruby on rails 使用回形针加速S3上传,ruby-on-rails,paperclip,Ruby On Rails,Paperclip,我用回形针上传S3中的图像。 但是我注意到这个上传速度非常慢。我认为,因为在完成提交之前,文件必须经过我的服务器,进行处理并发送到S3服务器 有什么方法可以加速这一过程吗 谢谢您想让上传的外观更快,还是让上传速度更快 如果是前者,您可以将图像处理逻辑放入后台任务中,方法如下。这样,当用户单击按钮时,他们将在您处理图像时立即转到下一页(您可以显示“正在处理”图像占位符,直到任务完成) 如果是后者,则完全取决于您的服务器和internet连接。你在哪里托管?直接上传到S3怎么样 不确定回形针是否能在
谢谢您想让上传的外观更快,还是让上传速度更快 如果是前者,您可以将图像处理逻辑放入后台任务中,方法如下。这样,当用户单击按钮时,他们将在您处理图像时立即转到下一页(您可以显示“正在处理”图像占位符,直到任务完成)
如果是后者,则完全取决于您的服务器和internet连接。你在哪里托管?直接上传到S3怎么样 不确定回形针是否能在开箱即用,但你可以做到
正如cwninja所建议的,我们直接上传到s3,以避免额外的上传。我们使用本博客文章中描述的插件的修改版本: 我们的被修改为处理多个文件上传(重写flex对象)
不确定这对回形针的效果如何,我们使用了附件,但让它与回形针配合使用并没有那么糟糕。使用延迟作业,这是一个很好的例子
或者您可以使用flash upload。如果您最终选择直接上传到S3,从而从Rails服务器卸载工作,请查看我的示例项目: 使用Rails 3、Flash和基于MooTools的FancyUploader直接上传到S3的示例项目: 使用Rails 3、Flash/Silverlight/GoogleGears/BrowserPlus和基于jQuery的Plupload直接上传到S3的示例项目: 顺便说一句,你可以用回形针做后处理,就像这篇博文描述的:
您没有发布任何代码,因此我将在这里做一些假设:
- 在您的项目中,您有一个
和相册
模型图像
- 一本
相册有许多:图像
- 你已经有了 及 使用铲斗和所有其他工具正确设置
- 您正在一次上载多个图像
<%= form_for @album, html: { multipart: true } do |f| %>
<%= f.file_field :files, accept: 'image/png,image/jpeg,image/gif', multiple: true %>
<%= f.submit %>
<% end %>
这正是最重要的内容。使用此设置,在本地服务器上平均执行22个图像(总计12MB)需要:files=
方法41.1806895秒。要检查方法运行所需的时间,请使用:
def files=(array = [])
start = Time.now
array.each do |f|
images.create file: f
end
p "ELAPSED TIME: #{Time.now - start}"
end
您要求更快地上传许多图像。有几种方法可以做到这一点。使用
无法工作,因为无法将图像等复杂数据传递给作业
改为使用。它将图像样式创建(如
缩略图:“500x500”
)移动到后台作业中
Gemfile
source 'https://rubygems.org'
ruby '2.3.0'
...
gem 'delayed_paperclip'
...
图像文件
class Image < ApplicationRecord
...
process_in_background :file
end
您可能会尝试此操作,但会出现一些奇怪的错误,只看到保存了4个图像。您还必须使用。此外,您不能在线程上使用:join
,因为如果您加入,该方法将等待线程完成运行
def files=(array = [])
semaphore = Mutex.new
array.each do |f|
Thread.new do
semaphore.synchronize do
images.create file: f
end
end
end
end
通过对方法的简单更改,并且没有添加gems,与以前相同的上传运行时间为0.017628秒。即1313比delayed_回形针
快。它也比常规设置快2336倍
如果使用
延迟回形针
和线程
,会发生什么情况
不要更改:files=
方法。只需在GEM文件中重新打开延迟回形针
,并在背景:file行中重新添加过程
在我的机器上进行此设置后,该方法平均运行时间为0.001277秒。这就是
- 13.8比
线程快几倍
- 18120.6比
delayed\u回形针快几倍
- 32248.0比常规设置快几倍
记住,这是在我的机器上,我还没有在生产中测试过。我也使用wifi,而不是以太网。所有这些都会改变结果,但我认为数字本身就说明了问题
上传图片更快。完成
更新:不要使用延迟的回形针
。这会导致数据库繁忙,一些图像可能无法保存。我已经测试过了。我认为只使用线程已经足够快了。从图像
文件中删除后台进程
行。另外,我的文件=
方法如下所示:
def files=(array = [])
Thread.new do
begin
array.each { |f| images.create file: f }
ensure
ActiveRecord::Base.connection_pool.release_connection
end
end
end
注意:因为我们将图像保存推送到后台任务,然后重定向。加载的页面上还没有图像。用户必须
更新页面。解决此问题的一种方法是使用
.
轮询是指JavaScript每隔5秒左右检查一次任何更改,并对页面进行更改(如果有)
另一个选择是使用
.
现在我们有了Rails 5,我们可以使用它了。每次创建图像时,我们都会广播相册的更新。如果用户在该相册的页面上,他们将在数据库上看到更新,而无需用户刷新或浏览器在无限循环中每5秒发出一次请求
很酷的东西。新链接在这里:我刚刚修复了损坏的链接。
class Image < ApplicationRecord
...
process_in_background :file
end
def files=(array = [])
threads = []
array.each do |f|
threads << Thread.new do
images.create file: f
end
end
threads.each(&:join)
end
def files=(array = [])
semaphore = Mutex.new
array.each do |f|
Thread.new do
semaphore.synchronize do
images.create file: f
end
end
end
end
def files=(array = [])
Thread.new do
begin
array.each { |f| images.create file: f }
ensure
ActiveRecord::Base.connection_pool.release_connection
end
end
end