似乎 Celery (v4.1) 既可以与一些任务的预取一起使用,也可以与CELERY_ACKS_LATE=True
一起使用(在这里讨论)
我们目前使用CELERY_ACKS_LATE=False
和CELERYD_PREFETCH_MULTIPLIER=1
在这两种情况下,Rabbit 中都有未确认的消息。
有时我们会遇到网络问题,导致 Celery 失去与 Rabbit 的连接几秒钟,并收到以下警告:consumer: Connection to broker lost. Trying to re-establish the connection...
发生这种情况时,未确认的消息会变回Ready
,这似乎是标准行为,并且正在被另一个消费者消费。
这会导致任务的多次执行,因为使用者在工作进程中启动了预取的任务,但无法将其交给 Rabbit。
由于似乎不可能保证任务在没有外部工具的情况下在 Celery 中只执行一次,那么如何确保任务最多执行一次?
-----编辑----
我正在考虑的一种方法是使用任务的self.request.delivery_info['redelivered']
并失败redelivered
的任务。
在实现"最多执行一次"的目标时,误报率很高(尚未执行的任务)
任务执行一次与多次执行任务时有额外的副作用之间存在差异,即。 如果您的任务不是幂等的,那么执行两次相同的任务将导致错误。
我建议的是允许任务执行多次,但使它们幂等,这样如果它们已经执行,它们就不会生效。