正确的方式来实现独立的Grails批处理?

问题描述:

我要实现以下几点:Grails的正确的方式来实现独立的Grails批处理?

  1. Web应用程序去的MongoDB数据库
  2. 长时间运行的批处理进程填充,并在后台更新该数据库

我想为这两个他们重复使用相同的Grails服务和相同的GORM域类(使用Grails的mongodb插件)。

对于Web应用程序,一切都应该正常工作,包括动态GORM查找程序方法。

但我无法弄清楚如何实现批处理。

a。如果我将它们实现为Grails服务方法,它们的长期性将成为问题。即使将它们包装在一些异步执行程序中也不会使所有事情复杂化,因为我希望它们各自成为一个单独的Java进程,以便它们可以被轻松地单独监控和停止。

b。如果我将它们作为src/groovy脚本实现并尝试从命令行启动,则无法正确注入Grails服务(ApplicationHolder方法会抛出NPE),或者让GORM查找程序方法正常工作。独立的GORM指南都考虑了Hibernate,总体而言,它似乎不是正确的路线。

c。我考虑过“批量启动器”Grails插件,但它未能安装,似乎有点遗弃。 d)。我认为'run-script'Grails命令可以从src/groovy中运行脚本,看起来它可能在开发中起作用,但在生产中似乎不是正确的事情。

我不能成为唯一的人有这样的问题 - 那么它通常如何解决?

人们如何运行与Grails应用程序共享代码库和数据库的独立脚本?

由于您希望作业处理位于与前端应用程序不同的JVM中,因此最简单的方法是运行两个Grails实例,一个用于提供Web请求的前端,以及另一个处理工作处理。幸运的是,丰富的Grails插件生态系统使得这种事情变得相当容易,但可能效率并不高,因为运行整个Grails应用程序仅仅用于处理就有点矫枉过正。

我倾向于这样做的方式是将我的应用程序编写为一个应用程序,并提供负责处理作业的服务。这些服务与RabbitMQ插件相关,所以一般流程是Web请求(或石英计划作业)将作业放入工作队列,然后工作服务负责处理它们。

这样做的好处是,由于它是一个应用程序,我可以完全访问所有的域对象等,我可以利用消息队列的非连接性来扩展我的前台和后台服务器,单独结束而不需要一个以上的应用程序。相反,我可以多次安装相同的应用程序,并配置专用于处理作业的线程数和/或作业处理器正在查看的队列。

所以,通过这种设置,对于开发,我通常只需将作业处理线程的数目设置为我正在开发的工作的任何有意义的数据,然后只是一个简单的grails run-app,而且我拥有完整的功能系统(假设我有一个RabbitMQ服务器也在运行)。

然后,当我开始部署到生产环境中时,我部署了两个应用程序实例,一个用于前端工作,另一个用于后端工作。我只是将前端实例配置为有1个或0个线程用于处理作业,而后端实例则提供更多线程。这让我可以根据需要更新任意部分,或者如果我需要缩放一个部分或另一个部分,则可以旋转更多实例。

我敢肯定还有其他方法可以做到这一点,但我发现这两个方法都很容易开发(因为它是一个应用程序),并且真的很容易部署,扩展和维护。

+0

这是有道理的。但是,如何启动处理传入的RabbitMQ任务的线程?用Grails的执行器插件还是其他方式? 我的问题是任务的运行时间非常长(小时),所以我宁愿将每个任务都作为单个进程来管理,但我想这是不可能的。 – 2012-08-02 18:34:22

+0

我只依靠Grails RabbitMQ插件来管理线程,所以消息只是传递给'handleMessage'方法,并且它可以处理消息(这是本例中的一项工作)所需的任何东西。对于长时间的任务,我唯一需要考虑的就是RabbitMQ服务器可能会发生的任何ACK超时(可能需要调整这些超时),否则应该没有任何问题。这就是消息队列的美妙之处......这些工作只会等到他们拿起来,所以运行时间并不重要。 – cdeszaq 2012-08-02 18:43:08

+0

要管理每个任务,只需将每个任务作为自己的服务,然后为每个您希望单独管理的服务创建一个应用程序实例。它们的关键在于使用外部配置config.groovy文件来覆盖主要config.groovy中的“默认值”,以便您可以调整RabbitMQ交换/队列绑定(以便能够忽略应用程序实例的某些作业队列)以及并发消费者的数量。 – cdeszaq 2012-08-02 18:50:55