使用RabbitMQ作为分布式代理-如何序列化每个队列的作业
我的系统中的每个作业都属于一个特定的用户ID,可以从多个源放入rabbitmq中。我的要求:使用RabbitMQ作为分布式代理-如何序列化每个队列的作业,rabbitmq,message-queue,worker,job-queue,Rabbitmq,Message Queue,Worker,Job Queue,我的系统中的每个作业都属于一个特定的用户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
}
}
}
或者,如果等待的作业位于每个用户的消息队列中,则事务将更容易处理,并且通过循环的单个协调器将不需要担心多线程问题
使事情在数据库和队列之间完全事务化可能很困难,但不需要这样做。引入挂起状态时,您应该允许您在谨慎方面出错,确保在某个步骤失败时不会丢失任何作业。您能提供更多的上下文吗?例如:作业如何提交到队列?它们的寿命有多长?它们被可靠地持久化有多重要?是的,这里需要更多的上下文。如果您有多个消费者在监听每个用户队列,我不认为有任何简单的方法可以确保每个用户一次只运行一个作业,而不会陷入黑客攻击或需要实现您自己的锁定机制。我对问题进行了编辑,以使其更清楚。谢谢你的帮助