Python 如何使用芹菜、RabbitMQ和Django确保每个用户的任务执行顺序?

Python 如何使用芹菜、RabbitMQ和Django确保每个用户的任务执行顺序?,python,django,rabbitmq,celery,django-celery,Python,Django,Rabbitmq,Celery,Django Celery,我在经营Django、芹菜和兔肉。我试图实现的是确保与一个用户相关的任务按顺序执行(具体来说,一次执行一个任务,我不希望每个用户都有任务并发性) 无论何时为用户添加新任务,它都应取决于最近添加的任务。如果此类型的任务已为此用户排队且尚未启动,则其他功能可能包括不将任务添加到队列 我做了一些研究,并: 我找不到一种方法来链接新创建的任务和芹菜中已经排队的任务,链似乎只能链接新任务 我认为这两种功能都可以通过自定义RabbitMQ消息处理程序实现,尽管可能很难编写代码 我也读过芹菜tasktr

我在经营Django、芹菜和兔肉。我试图实现的是确保与一个用户相关的任务按顺序执行(具体来说,一次执行一个任务,我不希望每个用户都有任务并发性)

  • 无论何时为用户添加新任务,它都应取决于最近添加的任务。如果此类型的任务已为此用户排队且尚未启动,则其他功能可能包括不将任务添加到队列
我做了一些研究,并:

  • 我找不到一种方法来链接新创建的任务和芹菜中已经排队的任务,链似乎只能链接新任务
  • 我认为这两种功能都可以通过自定义RabbitMQ消息处理程序实现,尽管可能很难编写代码
  • 我也读过芹菜tasktree,这可能是确保执行顺序的最简单方法,但如何将新任务与已应用的“
    applicated\u async
    ”任务树或队列链接?是否有任何方法可以使用此软件包实现额外的无重复功能
编辑:在中也有这个“锁”的例子,由于这个概念很好,我看不到一种可能的方法使它按我的情况下的预期工作-简单地说,如果我不能为用户获取锁,任务将不得不重试,但这意味着将它推到队列的末尾


这里最好的做法是什么?

如果您配置芹菜工人,使他们一次只能执行一个任务(请参见设置),那么您可以在每个用户的基础上强制执行所需的并发性。使用类似的方法

 NUMBER_OF_CELERY_WORKERS = 10

def get_task_queue_for_user(user):
    return "user_queue_{}".format(user.id % NUMBER_OF_CELERY_WORKERS)
要根据用户id获取任务队列,每个任务将被分配给每个用户的同一队列。工人需要配置为仅使用单个任务队列中的任务

结果是这样的:

  • 用户49触发一个任务

  • 任务被发送到
    user\u queue\u 9

  • 当收听
    用户队列\u 9
    的唯一芹菜工作者准备使用新任务时,该任务将被执行

  • 但这是一个老套的回答,因为

    • 每个队列只需要一个芹菜工人是一个脆弱的系统——如果芹菜工人停止,整个队列就停止

    • 工人们运转效率低下


    我假设您在插入任务之前不知道特定用户的任务是什么?为什么不自己创建一个队列(每个用户)并让芹菜从那里接收任务?在此基础上,为什么不使用十个桶,并使用“user.id%10”或字符串“hash(user.id)%10”映射到队列?谢谢,您已经意识到我还没有解决问题的并发部分——我的答案目前还不正确。