我目前正在评估Gearman在我们的后端部署一些昂贵的数据导入作业。到目前为止,这看起来很有希望然而,有一件丢失,我似乎无法找到任何信息。 如何从Gearman获取日程安排工作列表?
我意识到我可以使用管理协议来获取每个功能的当前排队作业的数量,但我需要有关实际作业的信息。还可以选择使用持久队列(例如MySQL)并查询数据库中的作业,但是我觉得绕过Gearman获取这类信息是非常错误的。除此之外,我没有想法。
可能我根本不需要这个:)所以这里有一些关于我想做什么的背景知识,我会全力以赴提出更好的建议。客户端和工作者都在PHP中运行。在我们的管理界面中,管理员可以触发客户端的新导入;因为导入需要一段时间才能作为后台任务启动。现在我想要回答的简单问题:这个客户端的最后一次导入运行是什么时候?导入是否已排队等候此客户端(在这种情况下,触发新导入应该没有效果)?很高兴:队列中的哪个位置是这个工作(所以我可以估计它何时运行)?
谢谢!
答案 0 :(得分:3)
Admin协议是您通常使用的协议,但正如您所发现的那样,它不会列出队列中的实际任务。我们通过跟踪我们在应用程序层中启动的当前任务来解决这个问题,并在我们的工作人员中通过回调来告知应用程序何时完成任务。这允许我们在任务完成时执行清理,通知等,并允许我们将此逻辑保留在应用程序中而不是工作程序本身。
关于进度,最好的方法是在Gearman中使用内置的进度机制,在PHP模块中,您可以使用$job->sendStatus(percentDone, 100)
来调用它。然后,客户端可以使用任务句柄从服务器检索此值(在启动作业时将返回该句柄)。这将允许您在界面中向用户显示当前进度。
只要您的应用程序中有当前正在运行的任务,您就可以使用它来回答已经运行的类似任务,但您也可以使用gearman的内置作业合并/重复数据删除;添加任务时请参阅$ unique参数。
当前队列中的位置将无法通过Gearman获得,因此您也必须在您的应用程序中执行此操作。我不会向Gearman持久层询问此信息。
答案 1 :(得分: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次,如果仍然失败,可以稍后检查作业。