【问题标题】:How can I prevent similar queues from running at the same time?如何防止类似的队列同时运行?
【发布时间】:2015-07-28 11:34:26
【问题描述】:

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

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

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

是否可以为每个agent_id 实现锁定样式功能,以便如果某个特定agent_id 的作业已经在运行,它将把它发送回队列?还是 beanstalkd 的任何功能允许这样做?

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

【问题讨论】:

    标签: multithreading laravel beanstalkd


    【解决方案1】:

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

    选项可以是内部速率限制系统,也可以是某种常见的原子锁定系统。一个 memcached 或 redis 服务器,其中一个 worker 尝试设置一个 lock-key,并且只有成功设置它的代理才能处理任务。这样做的好处可能是,一旦 API 请求完成,您就可以解除锁定,然后在工作人员处理结果时,另一个工作人员可以发出新请求。

    【讨论】:

    • 是的,我喜欢这个想法,我可能会为此使用 laravel 内置的缓存功能,并为我要处理的代理设置缓存,Cache::put(agent_id, true),然后在处理之前检查缓存。如果它已经在缓存中,则将其发送回队列 30 秒。
    • 我倾向于将 N 秒超时(如果成功)放入缓存(并且您不能覆盖内容)。回读,如果代理 === 我,则从 API 中获取,删除缓存并处理。或者,如果可以的话,从 API 中获取并将其放入队列中。
    猜你喜欢
    • 2020-04-28
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 2015-07-26
    • 2011-09-10
    相关资源
    最近更新 更多