在典型的 Web 应用程序中,有些事情我更愿意作为延迟的作业/任务来运行。它们往往具有以下部分或全部属性:
- 需要很长时间(从几秒到几分钟到几个小时)。
- 大量占用部分资源(CPU、网络、磁盘、外部API限制等)
- 结果不是立即需要的。没有它也能完成HTTP响应。可以(甚至可能更好)推迟到晚些时候。
- 可以(并且可能更愿意)在与 Web 服务器不同的机器上运行。这些机器可能是专用的作业/任务运行者。
- 应运行以响应其他事件,或定期启动。
在 Scala + Play Framework 2.x 应用程序中设置、排队、安排和运行延迟作业/任务的首选方式是什么?
更多细节...
我过去使用过的模式(如果适用的话我想复制它)是:
- 在 Web 请求的处理程序中,或在类似 cron 的调用中,将作业排队
- 在作业运行程序中,一次重复出列并运行一项作业
- 可能处理记录作业结果
这似乎是一个相对简单但仍然相对灵活的模式。
我过去遇到过的例子包括:
- 更新数据库中的派生数据
- 针对 Web 请求的分析/跟踪 API 调用
- 删除过期的会话或其他陈旧/过时的数据库记录
- 定期批量 ETL
在其他语言/框架中,我通常会使用作业/任务框架。示例包括:
- Ruby + Rails 应用程序中的 Resque
- Python + Django 应用程序中的 Celery
我找到了以下现有材料,但不幸的是,我认为它们不直接适合我的用例。
-
Play 1.x 异步作业 API https://www.playframework.com/documentation/1.2.3/jobs(+引用它的各种SO问题)。似乎已在 2.x 行中删除。没有提及替代它的内容。
-
玩 2.x Akka 集成 https://www.playframework.com/documentation/2.0.4/ScalaAkka。看起来非常通用。我想可以使用 Akka 来实现上述目的,但如果已经存在,我不想编写作业/任务框架。此外,没有关于如何将作业运行器计算机与 Web 服务器分开的信息。
-
这个答案 https://stackoverflow.com/a/15123249/904117。似乎对于“短到中等持续时间 IO 限制”的情况有潜在的希望,例如分析调用,但不一定适用于“CPU 限制”情况(可能不应该占用 Web 服务器上的 CPU,更喜欢发送到不同的节点)、“大量网络”情况或“多个小时”情况(可能不应该将其留在网络服务器的后台,即使它没有消耗太多资源)。
-
这个问题以及相关问题 https://stackoverflow.com/q/9339714/904117。与上面类似,在我看来,这仅涵盖适合在同一 Web 服务器上运行的情况。
关于用例的一些进一步说明(根据评论者的要求)。我在 resque 或 celery 等方面经历过两个主要用例,我试图在这里复制它们:
- 网站上的某些事件(大多数情况下,传入的 Web 请求会导致任务排队。)
- 任务应该定期运行。 (大多数情况下,这被实现为:定期将要运行的任务排入队列,如上所述。)
在 resque 或 celery 的情况下,两个用例排队的任务以相同的方式进入队列,并由运行程序/工作进程以相同的方式处理。排除其他 Scala 或 Play 特定的考虑因素,这将是我对如何解决这个问题的初步猜测。
关于为什么我不相信 Akka 调度程序适合我开箱即用的用例的一些进一步说明(根据评论者的要求):
虽然毫无疑问可以使用 Akka 调度程序(用于定期作业)、akka-remote 和 akka-cluster(用于作业调用者和作业运行者之间的通信)的某种组合来构建合适的解决方案,但该方法需要一定的资源粘合代码本身几乎就是一个延迟作业框架。如果存在,我更愿意使用现有的开箱即用的解决方案,而不是重新发明轮子。
None
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)