正如@dectarin 所提到的,让多个工作人员监听多个作业队列将很难确保每个用户只执行一个作业。
我认为如果工作通过几个步骤会更好。
- 用户提交作业
- 作业按用户排队,直到没有其他作业在运行
- Coordinator 将作业放在工作人员使用的活动作业队列中
- 工人拿起工作并执行它
- Worker 将结果发布到结果队列中
- 结果被发送给用户
我不知道作业是如何提交到系统的,因此很难判断实际的每用户 MessageQueues 是否是排队等待的最佳方式。例如,如果作业已经放在邮箱中,那也可以。或者将排队的作业存储在数据库中,作为奖励,您可以编写一个小前端供用户检查和管理他们的排队作业。
根据您的选择,您可以找到一种优雅的方式来协调每个用户约束的单个作业。
例如,如果作业位于数据库中,数据库会保持同步,并且多个协调工作人员可以通过以下循环:
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
}
}
}
或者,如果等待作业位于每个用户的消息队列中,则事务将更容易,并且通过循环的单个 Coordinator 无需担心多线程。
跨数据库和队列使事物完全事务化可能很困难,但不是必需的。引入挂起状态时,您应该允许您谨慎行事,以确保在步骤失败时不会丢失工作。