3

我想实现以下内容:

  1. Grails 中的 Web 应用程序将转到 MongoDB 数据库
  2. 长期运行的批处理在后台填充和更新该数据库

我希望他们两个都重用相同的 Grails 服务和相同的 GORM 域类(使用 Grails 的 mongodb 插件)。

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

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

一种。如果我将它们实现为 Grails 服务方法,它们的长期运行性质将是一个问题。即使将它们包装在一些异步执行器中也会不必要地使一切复杂化,因为我希望它们每个都是一个单独的 Java 进程,以便可以轻松地单独监视和停止它们。

湾。如果我将它们实现为 src/groovy 脚本并尝试从命令行启动,我无法正确注入 Grails 服务(ApplicationHolder 方法抛出 NPE)或让 GORM finder 方法工作。独立的 GORM 指南都考虑到了 Hibernate,总体而言,这似乎不是正确的途径。

C。我考虑过'batch-launcher' Grails 插件,但它未能安装并且似乎有点被遗弃了。

d。我考虑使用'run-script' Grails 命令从 src/groovy 运行脚本,它似乎实际上可能在开发中工作,但在生产中似乎不是正确的做法。

我不可能是唯一一个遇到这种问题的人 - 那么它通常是如何解决的呢?

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

4

1 回答 1

3

由于您希望作业处理与前端应用程序位于单独的 JVM 中,因此最简单的方法是运行两个 Grails 实例,一个用于服务 Web 请求的前端,另一个用于处理与作业处理。

值得庆幸的是,Grails 丰富的插件生态系统使这种事情变得相当容易,尽管可能不是最有效的,因为运行整个 Grails 应用程序只是为了处理有点过分。

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

这样做的好处是,因为它是一个应用程序,所以我可以完全访问所有域对象等,并且我可以利用消息队列的断开连接特性来分别扩展我的前端和后端,而无需一个以上的应用程序。相反,我可以多次安装同一个应用程序并配置专用于处理作业的线程数和/或作业处理器正在查看的队列。

因此,通过这种设置,对于开发,我通常会将作业处理线程的数量设置为对我正在做的开发工作有意义的任何东西,然后只是一个简单grails run-app的,我有一个功能齐全的系统(假设我有一个运行的 RabbitMQ 服务器也可以使用)。

然后,当我部署到生产环境时,我部署了 2 个应用程序实例,一个用于前端工作,另一个用于后端工作。我只是将前端实例配置为具有 1 个或 0 个线程来处理作业,而后端实例则提供更多线程。这使我可以根据需要更新任一部分,或者如果我需要扩展一个部分或另一个部分,则可以启动更多实例。

我确信还有其他方法可以做到这一点,但我发现这既容易开发(因为它只是一个应用程序),而且也很容易部署、扩展和维护。

于 2012-08-02T13:59:38.827 回答