问题描述
如果我想同时处理多个作业,我不知道应该如何进行。
我有一个 rails API,其中一项任务是获取其他 api。此任务需要很长时间,因为它对其他 api 进行了多次调用。 目前我所做的是创建一个活动作业并在有人想要启动此任务时调用 perform_later 方法(从控制器)。 但是如果有多个用户要求运行这个任务,我的理解是每个任务都会被一个一个的排队处理,我并不真正想要,因为这意味着一些用户将不得不等待很长时间。
如果我有不同的用户要求执行此特定任务,我想要的是活动作业一次处理多个任务。
我应该如何进行?
我尝试从 perform_later 方法切换到执行,但是当一个任务正在运行时,如果我尝试调用我的 rails api,我的请求将被搁置,直到第一个任务完成。 任何澄清或帮助表示赞赏。 谢谢!
解决方法
Rails 带有一个名为 Active Job 的后台处理框架。它可以让你告诉 rails 你想要一些代码由另一个进程(而不是应用程序服务器)执行。由于关于如何处理后台作业有很多选择,ActiveJob 只是一个用于处理后台作业的 API,而实际的工作是由一个 Adapter 完成的,非常类似于 ActiveJob 只是一个 API 和真正编写的方式数据库是由不同的适配器完成的,这些适配器知道如何与不同的数据库通信。
开箱即用的 Active Job 将使用异步适配器,这有利于开发,因为它无需额外设置即可启动工作程序(使用 Concurrent Ruby)。不好的部分是它只会启动这些工人中的 1 个,这就是为什么你会看到你的工作被一个接一个地接走。
异步适配器不是为一次运行多个工作程序而设计的,并且当工作程序有时间执行它们时,它用来存储您的作业的队列不会持久化,因此每次您都会丢失排队的作业重启你的服务器。
您将需要切换到另一个队列适配器,让您可以根据需要启动任意数量的工作器,以便同时运行作业。如果您希望作业很少并且不想增加项目的复杂性,我建议使用 Delayed Job,因为它将使用您的数据库来存储作业队列。如果您希望一次有许多(数百个)作业排队,那么像 Sidekiq 或 Resque 这样的东西会更好,因为它们将作业队列移动到 Redis 服务器。
每个适配器都有自己的启动工作器的方式,因此请阅读您所使用的适配器的文档以根据需要启动尽可能多的工作器。例如。 RAILS_ENV=production script/delayed_job -n 2 start
在 DelayedJob 中