4

我目前正在评估 Gearman 以在我们的后端分出一些昂贵的数据导入工作。到目前为止,这看起来很有希望。但是,缺少一件我似乎无法找到任何信息的东西。如何从 Gearman 获取计划作业列表?

我意识到我可以使用管理协议来获取每个功能的当前排队作业的数量,但我需要有关实际作业的信息。还可以选择使用持久队列(例如 MySQL)并在数据库中查询作业,但绕过 Gearman 获取此类信息对我来说是非常错误的。除此之外,我没有想法。

可能我根本不需要这个:) 所以这里有更多关于我想做的背景,我愿意接受更好的建议。客户端和工作人员都在 PHP 中运行。在我们的管理界面中,管理员可以为客户触发新的导入;由于导入需要一段时间,因此它作为后台任务启动。现在我希望能够回答的简单问题是:该客户端的最后一次导入是什么时候?该客户端的导入是否已排队(在这种情况下,触发新导入应该无效)?很高兴:这个工作在队列中的哪个位置(这样我可以估计它什么时候运行)?

谢谢!

4

2 回答 2

3

Admin 协议是您通常使用的,但正如您所发现的,它不会列出队列中的实际任务。我们通过跟踪我们在应用程序层中启动的当前任务来解决这个问题,并在我们的工作人员中有一个回调告诉应用程序何时任务完成。这允许我们在任务完成时执行清理、通知等,并允许我们将此逻辑保留在应用程序中,而不是工人本身。

与进度相关的最好方法是使用 Gearman 本身内置的进度机制,在 PHP 模块中,您可以使用$job->sendStatus(percentDone, 100). 然后,客户端可以使用任务句柄(将在您启动作业时返回)从服务器检索此值。这将允许您在界面中向用户显示当前进度。

只要您的应用程序中有当前正在运行的任务,您就可以用它来回答是否有类似的任务已经在运行,但您也可以使用 gearman 内置的作业合并/重复数据删除;添加任务时查看 $unique 参数。

当前队列中的位置将无法通过 Gearman 获得,因此您也必须在应用程序中执行此操作。我不会向 Gearman 持久层询问这些信息。

于 2012-06-25T14:21:25.067 回答
1

您几乎已经给了自己答案:使用 DBRMS(MySQL 或 Postgres)作为持久性后端并查询 gearman_queue 表。

例如,我们开发了一个混合解决方案:我们为作业生成并传递一个唯一 id,我们将其作为第三个参数传递给 doBackground() ( http://php.net/manual/en/gearmanclient.dobackground.php ) 在排队时工作。

然后我们使用这个 id 查询 gearman 表来验证查看 'unique_key' 表字段的作业状态。您还可以获取队列位置,因为记录已经排序。

Pro Bonus:我们还在工作人员内部捕获异常。如果作业失败,我们将作业负载(这是一个 JSON 序列化对象)写入文件,然后通过 cronjob 获取文件并重新排队作业,增加“重试”内部计数器,因此我们最多重试单个作业 3 次,如果仍然失败,请稍后检查作业。

于 2014-10-15T13:20:29.237 回答