如何防止类似队列同时运行?

时间:2015-07-28 11:34:27

标签: multithreading laravel beanstalkd

我们目前使用Laravel中的队列工作程序处理一组任务。当我使用php artisan queue:work个多个线程的作业最终一起运行时(异步)。我们使用Beanstalkd作为队列驱动程序。

问题在于,在队列工作中,我们正在轮询一个API,该API仅允许特定agent_id的一个并发会话。也就是说,一次只能运行一个具有相同agent_id的API调用。

我们考虑使用匹配php artisan queue:work的queue_name上的过滤器来启动多个agent_id线程,但是我们有超过500个代理,因此我们需要500个线程,所以这不是理想的。

是否有为每个agent_id实现锁定样式功能,以便如果某个作业已经针对特定agent_id运行,它会将其发送回队列?或者是否有beanstalkd的任何功能允许这个?

另一个选项也可以是在用户已经登录时优雅地处理来自API的拒绝(并将作业发送回队列)。但这可能会变得混乱,并可能使日志混乱。

1 个答案:

答案 0 :(得分:1)

您可以只运行一个能够运行fetch-from-API作业的工作者,也可以使用某种外部编组/锁定服务。

其选项可以是内部速率限制系统,也可以是某种常见的原子锁定系统。工作程序尝试设置锁定密钥的memcached或redis服务器,以及只有成功设置锁定密钥的代理程序才能处理该任务。这样做的一个优点可能是,一旦API请求完成,您就可以删除锁定,然后在工作人员处理结果时,另一个工作人员可以发出新请求。