Image Heavy App 的最佳 Ruby on Rails 架构

Posted

技术标签:

【中文标题】Image Heavy App 的最佳 Ruby on Rails 架构【英文标题】:Best Ruby on Rails Architecture for Image Heavy App 【发布时间】:2013-04-24 19:43:42 【问题描述】:

我正在构建一个允许一次上传大量照片的应用程序,并且想知道解决这个问题的最佳设置是什么。

这是我目前使用的:

Jquery 文件上传:允许用户拖放图片 CarrierWave:使用 ImageMagick 处理图像并调整其大小 Amazon S3:CarrierWave 通过 Fog 将图像上传到 Amazon S3 Heroku:用于托管

我想让用户能够将大量图像拖放到一个页面上,然后在后台进行上传时导航到其他页面。我还希望图片在上传完成时出现。我不希望这个过程锁定 Heroku dynos,所以我可能需要将工作转移到后台工作,但我不确定在我的情况下使用什么。

此类应用的最佳设置是什么?我应该使用什么后台工作者 gem? Cloudinary 是个好主意吗?

【问题讨论】:

为网络服务器添加上传模块以避免文件复制时不必要的 CPU 使用率 【参考方案1】:

在您提到之前我从未见过 Cloudinary,但它似乎非常适合您的项目。

首先,它可能会极大地简化您的应用。 Cloudinary 通过其 HTTP API 支持 direct uploads from the browser,并且已经有一个基于 jQuery File Upload 的 jquery plugin 并且具有类似的功能,包括客户端预上传处理。

此外,它支持类似于dragonfly 的即时转换(也是一个非常好的库)。

这意味着,除非您确实需要通过您的应用上传这些图像,否则您可以完全绕过它,直接上传到 Cloudify 并通过他们的transformation API 处理图像裁剪和其他转换。

如果需要,您可以从应用程序中删除 Carrierwave 和 S3,当然也不需要任何背景测功机来处理图像处理。此外,它可能会更快(直接上传和即时操作与上传到您的应用、处理然后上传到云端相比),并且会消除通过您的应用上传的带宽。

即使没有直接上传,Cloudinary 似乎也提供了一个 Carrierwave 插件,它仍然可以使用他们的转换 API,从而避免您的应用程序处理图像的需要。

【讨论】:

这是否允许用户发布一组照片,然后在后台上传(这样他们就可以在不停止上传过程的情况下离开页面)? 如果不打开弹出窗口来处理上传,我不会看到这种情况发生。否则当您离开页面时,它将中断上传。据我所知,网络浏览器中没有进程背景。 但是,根据您的操作,您仍然可以向堆栈添加某种推送组件,例如 Faye 或一些 WebSocket 实现,它们可以让您推送上传图像的通知。【参考方案2】:

我最近在 Heroku 上构建了一个接受大量上传的应用程序。我决定构建自己的解决方案,而不是使用 cloudinary 或等效的。以下是我学到的一些经验教训:

不要上传到heroku。在整个上传期间,您的整个网络工作者都将被锁定。最多一分钟。不可接受。

使用 javascript 上传器(如 jquery-file-upload)直接上传到 s3。一开始这有点复杂,但一旦你开始工作,它就很棒了。您可以使用s3_direct_upload gem,或者您可以阅读他们的源代码,从头开始制作您自己的解决方案。该宝石基于railscasts pro 剧集,您必须付费,但有source available。

上传完成后,向您的应用程序发出 ajax 请求,将新的 s3 url 作为remote url 传递。然后,Carrierwave 将在 s3 上处理图像,就像上传图像一样,只是在几秒钟而不是一分钟内。

使用 jquery-file-upload 的 client-side image resizing。有人会尝试上传一张 5MB 的照片,然后再抱怨上传需要永远。这将使所有上传在理论上尽可能快。

将 s3 配置为 clear your uploads folder automatically。

不要使用薄的。使用unicorn。几秒钟的时间太长了,无法处理瘦身请求,但是拥有三四个工人的独角兽要宽容得多。

不要使用 rmagick。它是用于复杂图像处理的更好的 API,但使用的内存量惊人。请改用 mini_magick。

您会注意到,我并没有为此使用后台工作人员。如果您真的感觉很细致,您可以让接收远程 url 的控制器将其工作传递给后台工作人员,如果您立即需要结果,后台工作人员可以通过 pubsub(faye 或 pusher,可能与令人兴奋的新sync gem)。但这对我的应用程序来说不是必需的,我宁愿把钱花在另一个 web dyno 上而不是 worker dyno 上。

而且,是的,如果您想让他们在此过程中点击整个应用程序,您将需要在弹出窗口中上传(并使用某种 pubsub 解决方案),或者构建您的整个网站作为使用 ember 或骨干或 Angular 或其他任何东西的 javascript 应用程序。

有什么问题吗?

【讨论】:

在网络测功机上进行任何处理(即使只是几秒钟)都会出现响应问题。 Heroku 的负载平衡层不再知道每个 dyno 是否实际可用于处理请求。请求被随机负载平衡到所有 dyno,来自其他用户的请求最终可能会在您的图像处理请求作业后面等待 3-5 秒,即使另一个 dyno 能够立即处理请求。在 heroku 上保持请求的速度总是最好的。Source Article 同意。这就是为什么 heroku changed their official recommendation 从瘦到独角兽,问题不那么明显。最好的架构涉及工作人员,但可能并非所有应用程序都需要它,并且肯定不会产生与直接 s3 上传等相同的影响。

以上是关于Image Heavy App 的最佳 Ruby on Rails 架构的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 块的最佳解释? [关闭]

Ruby 类方法或常量,最佳实践

ruby 中没有扩展数组的最佳链表?

将 SOAP 与 Ruby 结合使用的最佳方式是啥?

在 ruby​​ on rails 上重命名上传文件

ruby image_proxy_controller.rb