在Grails应用程序中建立长时间运行作业队列的最佳方法是什么?

7
我有一个Grails应用程序,其中包含一些计算密集型优化,运行时间约为5分钟(可能更长)。目前,我正在主请求线程中执行这些操作,即请求需要5分钟才能返回。虽然它可以工作,但从可用性的角度来看,当然很糟糕。
那么最好的实现异步处理的方式是什么呢?我想涉及到ThreadPoolExecutor,但如何启动和访问它呢?我可以将其建模为Grails服务吗?或者作为Job(似乎只适用于定期任务)?
此外,处理作业状态的最佳方法是什么?通过标志还是可能是DB中的整个新类?让浏览器显示旋转图标并持续轮询直到状态改变?
6个回答

3

Background-thread插件已经过时,我不建议使用它。而且JMS似乎对于后台处理来说有些大材小用。JMS更像是一个消息队列,而不是后台处理工具。

我建议使用Quartz插件或者使用gpars。


3

有一个Grails插件background-thread,可能正是您要寻找的。

当然,您也可以自己编写线程池或使用现有的Java工具。


3
我会使用grails的JMS插件来完成这个任务。
然后,您可以创建一个具有“onMessage”方法的服务,该方法会自动与底层jms提供程序(如OpenMQActiveMQ)交互。
这使得这种事情变得非常容易。

与仅使用ThreadPoolExecutor相比,这有什么好处?听起来比那要复杂得多。 - Michael Borgwardt
它肯定更加复杂。主要的好处将围绕一些监控和轮询功能展开,这些功能是你的问题所提到的一些要求。在JMS世界中,很多这样的问题都得到了解决,但是需要更多的设置/维护。这真的取决于你的需求有多“企业级”。如果你不太关心监控或者容器在处理过程中崩溃时会发生什么,那么我会选择更简单的方案。这只是一个潜在的选择。 - Ted Naleid
1
啊,我明白了。那么,我所需要的唯一监控是用户等待特定作业完成。我也不需要事务安全性,所以我会选择更简单的方法。 - Michael Borgwardt

2

为了贯彻“能够运作的最简单方法”原则,我将其作为一个简单服务来实现。当然,它可能过于简单,欢迎批评。

我使用了Groovy的特性,即Thread具有一个静态start方法,可以接受一个闭包。请参见http://groovy.codehaus.org/groovy-jdk/java/lang/Thread.html

我在服务上实现了一个类似以下的方法:

synchronized def runThreadedTask() {
  if(taskRunning) { 
    // taskRunning is defined as a service level flag to monitor job status
    // if we are already running the task just return
    return;
  }

  Thread.start {
    taskRunning = true
    // do job processing here
    taskRunning = false
  }
}

1

Grails 安装插件 background-thread

定义后台服务

backgroundService.execute("正在处理", {

// 在此处执行工作

});


1

虽然这个问题已经有一段时间了,但由于它刚刚在搜索中出现,我想补充一下:现在Thread对象中有一个Groovy线程闭包。你只需要使用:

Thread.start {
    // 异步代码放在这里
}

就可以愉快地结束了。当异步代码完成时,您的异步代码可以调用更新数据方法或其他方法--如果您可以运行多个线程,则可能需要同步。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接