在不加载多个环境的情况下为多个 Rails 应用程序安排任务
在我们的服务器上,我们使用 Phusion Passenger 部署了多个 Rails 应用程序。每个应用程序都有一组必须定期计划和运行的任务(通常是清除缓存、发送邮件等)。
我在野外看到的所有示例通常都显示一个单独的守护进程,用于处理应用程序的计划任务。但是,这需要守护程序加载应用程序的环境。虽然这在您部署一两个应用程序时有效,但当服务器上可能部署 100 个应用程序时,它就无法扩展。 (例如,每个“守护进程”加载整个 Rails 环境加上应用程序代码,可能超过 50MB。部署 100 个应用程序,仅在调度程序守护进程中就消耗了 5GB。)
有人解决了这个问题吗?
On our servers we have deployed multiple Rails applications using Phusion Passenger. Each application has a set of tasks that must be scheduled and run periodically (the usual clear caches, send mail, etc.)
All the examples I've seen in the wild usually show a separate daemon that handles the scheduled tasks for an application. However, this requires that the daemon load the app's environment. While this works when you have one or two apps deployed, it does not scale when there might be 100 apps deployed on a server. (For example, each "daemon" loads up an entire Rails environment plus the app code, which could be well over 50MB. Deploy 100 apps, and you're chewing up 5GB just in scheduler daemons.)
Has anyone solved this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我有类似的问题需要解决。我发现这些解决方案可用:
优点
最后我决定采用选项 4。使用 cron 和curl(或 wget),并拥有只能由本地主机访问的
CronController
。I had similar issue to solve. I found these solutions available:
Finally I decided to go with option 4. Using cron and curl (or wget), and own
CronController
accessible only to localhost.我认为答案取决于您的需求。如果这些任务需要相当多的时间,那么最简单的解决方案就是使用守护程序以传统方式完成。如果您想依赖 Rails 堆栈,那么您必须将其加载到内存中才能使用它 - 您将无法转义它。
如果您的任务不需要太多时间,那么您可以执行以下操作:使用可用的方法(例如 delayed_job< /a>),但定期启动和停止守护进程(请参阅 此处获取一些提示)。因此,您可以在上午 9 点启动 10 个守护进程,并在上午 10 点停止它们,然后您可以启动另外 10 个守护进程,依此类推。启动和停止可以使用 cron 或任何类似的工具来完成。
但是,如果您的任务非常简单并且在每个应用程序中都非常相似,那么您只需编写脚本来完成这项工作即可。例如,如果“通常清除缓存”意味着您从某些目录中删除一些文件,那么只需将其放入脚本并定期运行即可。发送电子邮件也可以通过脚本(ruby 程序)来完成。在 ruby 中从数据库中获取任何数据真的很容易。所以这个程序可以定期检查数据库中的
mails_queue
表并发送电子邮件。如果您的应用程序类似,那么实现起来将非常简单。也许有一些现成的解决方案,但我还没有听说过。
I think that the answer depends on your needs. If those tasks take quite a lot of time, then the simplest solution is to do it in traditional way with daemon. If you want to rely on Rails stack then you must load it to memory in order to use it - you won't escape it.
If your tasks don't need much time, then you can do something like this: use methods that are availble (like delayed_job) but start and stop daemon periodicaly (see here for some tips). So you can start 10 daemons at 9 a.m. and stop them at 10 a.m. Then you can start another 10 and so on. Starting and stopping can be done with cron or any similar tool.
However if your tasks are really simple and very similar in each application, then you can just write your scripts to do the job. On example if "usual clear cache" means that you delete some files from some directories, then just put it to script and run in periodicaly. Sending email can also be done through a script (ruby program). It is really easy to fetch any data from db in ruby. So this program can periodicaly check something like
mails_queue
table in databases and send emails. If your applications are similar then it will be quite simple to achieve.Maybe there are some ready solutions to this, but I haven't heard about them.