如何防止多个工作人员仅运行一次发送的任务?

Dej*_*kic 5 celery celery-3

最近我发现了一个奇怪的芹菜(3.1.25)行为.一个任务排队执行send_task() 使用一次,但是过了一段时间我看到多个运行相同的任务!我花了几个小时查看Celery文档,试图找出如何防止这种行为.任何帮助将不胜感激!

这是出于inspect active:

...
-> celery1@ec2-256-234-55-209.compute-1.amazonaws.com: OK
    * {'hostname': 'celery1@ec2-256-234-55-209.compute-1.amazonaws.com', 'id': '5bf971b7-c2d2-47a1-9e3e-abec6c3c7ab4', 'args': "['myex', 'equities', 20170103]", 'time_start': 1633747.663716712, 'name': 'parsing.2pass', 'acknowledged': False, 'delivery_info': {'exchange': 'celery', 'priority': 0, 'redelivered': None, 'routing_key': 'celery'}, 'worker_pid': 28649, 'kwargs': '{}'}
    * {'hostname': 'celery1@ec2-256-234-55-209.compute-1.amazonaws.com', 'id': '5bf971b7-c2d2-47a1-9e3e-abec6c3c7ab4', 'args': "['myex', 'equities', 20170103]", 'time_start': 1637348.143546186, 'name': 'parsing.2pass', 'acknowledged': False, 'delivery_info': {'exchange': 'celery', 'priority': 0, 'redelivered': None, 'routing_key': 'celery'}, 'worker_pid': 1550, 'kwargs': '{}'}
-> celery1@ec2-54-234-55-254.compute-1.amazonaws.com: OK
    * {'hostname': 'celery1@ec2-256-234-55-254.compute-1.amazonaws.com', 'id': '5bf971b7-c2d2-47a1-9e3e-abec6c3c7ab4', 'args': "['myex', 'equities', 20170103]", 'time_start': 1626395.204211438, 'name': 'parsing.2pass', 'acknowledged': False, 'delivery_info': {'exchange': 'celery', 'priority': 0, 'redelivered': None, 'routing_key': 'celery'}, 'worker_pid': 26978, 'kwargs': '{}'}
-> celery1@ec2-54-226-20-88.compute-1.amazonaws.com: OK
    * {'hostname': 'celery1@ec2-256-226-20-88.compute-1.amazonaws.com', 'id': '5bf971b7-c2d2-47a1-9e3e-abec6c3c7ab4', 'args': "['myex', 'equities', 20170103]", 'time_start': 1630146.08942695, 'name': 'parsing.2pass', 'acknowledged': False, 'delivery_info': {'exchange': 'celery', 'priority': 0, 'redelivered': None, 'routing_key': 'celery'}, 'worker_pid': 19473, 'kwargs': '{}'}
...
Run Code Online (Sandbox Code Playgroud)

请注意,该任务5bf971b7-c2d2-47a1-9e3e-abec6c3c7ab4至少在3个worker上运行,即使它是由单个 send_task()调用触发的.我们使用Redis作为所有默认值的经纪人(没有花哨的交易所和路线).

Nik*_*nko 1

此行为可能有多种可能的原因。

  • 也许您使用 celerybeat 服务启动了 celery。在这种情况下应该只有一个 celery 进程。在其他情况下,每个进程将安排相同的任务。
  • 也许你应该调整你的队列。由于redis使用广播消息来传递任务。更多信息请点击这里即使您没有使用预计到达时间/倒计时,这也可能是重复的原因

无论如何,您可以使用celery_once来防止这种情况发生。主要思想是检查任务是否已被提升并执行。是的,这看起来像是一个解决方法,但效果非常好。