使用RabbitMQ作为分布式代理-如何序列化每个队列的作业

使用RabbitMQ作为分布式代理-如何序列化每个队列的作业,rabbitmq,message-queue,worker,job-queue,Rabbitmq,Message Queue,Worker,Job Queue,我的系统中的每个作业都属于一个特定的用户ID,可以从多个源放入rabbitmq中。我的要求: 在任何给定时间,每个用户运行的作业不得超过1个 其他用户的作业不应因特定用户的作业堆积而受到任何延迟 每个作业应至少执行一次。每个作业都有一个最大重试次数,如果失败,将以延迟的方式重新插入队列(或可能延迟) 维护作业顺序(每个用户)是可取的,但不是强制性的 作业可能应该被持久化,因为我需要它们至少执行一次。工作没有到期时间 任何工人都应该能够为任何用户运行作业 有了这些需求,我认为为每个用户维护一个

我的系统中的每个作业都属于一个特定的用户ID,可以从多个源放入rabbitmq中。我的要求:

  • 在任何给定时间,每个用户运行的作业不得超过1个
  • 其他用户的作业不应因特定用户的作业堆积而受到任何延迟
  • 每个作业应至少执行一次。每个作业都有一个最大重试次数,如果失败,将以延迟的方式重新插入队列(或可能延迟)
  • 维护作业顺序(每个用户)是可取的,但不是强制性的
  • 作业可能应该被持久化,因为我需要它们至少执行一次。工作没有到期时间
  • 任何工人都应该能够为任何用户运行作业
有了这些需求,我认为为每个用户维护一个队列是有意义的。我还需要所有工作人员监视所有用户队列并为用户执行作业,该用户的作业当前没有在任何地方运行(即,每个用户不超过1个作业)


此解决方案在集群设置中使用RabbitMQ是否可行?由于队列的数量会很大,我不确定每个监视每个用户队列的工作人员是否会造成显著的开销。感谢您的帮助。

正如@dectarin所提到的,让多个工作人员监听多个作业队列将很难确保每个用户只执行一个作业

我认为如果这些工作经过几个步骤,效果会更好

  • 用户提交作业
  • 作业按用户排队,直到没有其他作业正在运行
  • 协调器将作业放入由工作人员使用的活动作业队列中
  • 工人拿起工作并执行它
  • 工作人员将结果发布到结果队列中
  • 结果将发送给用户
  • 我不知道作业是如何提交到系统的,所以很难说实际的每个用户消息队列是否是排队等待的最佳方式。例如,如果作业已经存在于邮箱中,那么这可能也会起作用。或者将排队的作业存储在数据库中,作为一项额外功能,您可以编写一个小前端,供用户检查和管理排队的作业

    根据您的选择,您可以找到一种优雅的方式来协调每个用户的单个作业约束

    例如,如果作业位于数据库中,则数据库会保持同步,多个协调工作人员可以通过以下循环:

    while( true ) {
        if incoming job present for any user {
            pick up first job from queue
            put job in database, marking it active if no other active job is present
            if job was marked active {
                put job on active job queue
            }
        }
        if result is present for any user {
            pick up first result from result queue
            send results to user
            mark job as done in database
            if this user has job waiting in database, mark it as active
            if job was marked active {
                put job on active job queue
            }
        }
    }
    
    或者,如果等待的作业位于每个用户的消息队列中,则事务将更容易处理,并且通过循环的单个协调器将不需要担心多线程问题


    使事情在数据库和队列之间完全事务化可能很困难,但不需要这样做。引入挂起状态时,您应该允许您在谨慎方面出错,确保在某个步骤失败时不会丢失任何作业。

    您能提供更多的上下文吗?例如:作业如何提交到队列?它们的寿命有多长?它们被可靠地持久化有多重要?是的,这里需要更多的上下文。如果您有多个消费者在监听每个用户队列,我不认为有任何简单的方法可以确保每个用户一次只运行一个作业,而不会陷入黑客攻击或需要实现您自己的锁定机制。我对问题进行了编辑,以使其更清楚。谢谢你的帮助