Rails控制器中的Process.fork

von*_*rad 4 ruby ruby-on-rails ruby-on-rails-3

我们正在做一个新应用程序的原型设计,并注意到其中一个操作需要永远加载(80-120秒).由于很多处理不需要在页面加载时发生(我们可以通过Ajax稍后请求数据),我想到使用Process.fork允许页面立即返回,而处理仍然发生在"幕后".

我们正在将Apache与Passenger一起用于该应用程序.

有几件事:

  1. 我知道delayed_jobs,resque,BJ和其他后台工作宝石.我们使用dj,最终也会使用类似的东西.在我们进行原型设计时,这是一个权宜之计.

  2. 我不关心服务器性能.该应用程序在自己的服务器上运行,只有少数用户尝试使用它.

早期测试表明这种方法效果很好,但我想知道使用它是否是个好主意.它会变得可靠吗?如果用户导航到另一个页面或关闭标签/浏览器,分叉过程是否会继续?fork完成后,进程是否会自行终止?

ger*_*tas 5

取决于"处理"的含义.通常,如果处理方式使用Rails堆栈,这将不可靠 - 因为请求释放的主进程可能被乘客分配给另一个请求,并且事情可能会出错.此外,Passenger可能会在某些情况下关闭主进程,从而关闭Rails实例(减少空闲实例池等).

通常,这可能导致过程泄漏,意外锁定,竞争条件,关闭时应用程序错误等.

我建议使用在Apache/Passenger堆栈外运行的工作程序,例如使用集群BackgrounDRb或其他解决方案(你提到Resque).

还有另一个想法,我目前用于我的应用程序的cron作业.我的crontab只是很少wget用于长时间运行的任务.您可以根据需要使用OpenURI在ruby fork中执行类似的操作.想象一下应用程序通过HTTP ping自己.分叉进程不再需要Rails - 它只是访问任务页面和下一个Passenger服务请求并管理此特殊请求的应用程序实例.

如果Passenger杀死fork的父进程并因此分叉进程 - 另一个Rails实例应该继续处理http请求.