Celery重启丢失计划任务

15 投票
1 回答
3877 浏览
提问于 2025-05-10 15:15

我用Celery来安排将来发送邮件的任务。我把任务放进Celery里,用apply_async()方法,并设置了一个将来要执行的时间(ETA)。

当我在Flower里查看时,看到所有安排在未来的任务状态都是RECEIVED。

如果我重启Celery,所有任务就消失了。为什么会消失呢?

我使用Redis作为消息中介。

编辑1

在文档中我发现:

如果一个任务在可见性超时内没有被确认,这个任务会被重新分配给其他工作者执行。

这会导致一些问题,特别是对于那些ETA(预计执行时间)/倒计时/重试的任务,如果执行时间超过了可见性超时,就会出现这个任务被重复执行的情况,形成一个循环。

所以你需要增加可见性超时,以匹配你计划使用的最长ETA时间。

需要注意的是,Celery在工作者关闭时会重新发送消息,因此如果可见性超时设置得很长,只会在发生电力故障或强制终止工作者时,延迟“丢失”任务的重新发送。

定期任务不会受到可见性超时的影响,因为这是一个与ETA/倒计时不同的概念。

你可以通过配置一个同名的传输选项来增加这个超时:

BROKER_TRANSPORT_OPTIONS = {'visibility_timeout': 43200}

这个值必须是一个整数,表示秒数。

但我的任务的ETA可能需要几个月甚至几年。

编辑2

当我输入以下命令时,得到的结果是:

$ celery -A app inspect scheduled

{u'priority': 6, u'eta': u'2015-11-22T11:53:00-08:00', u'request': {u'args': u'(16426,)', u'time_start': None, u'name': u'core.tasks.action_due', u'delivery_info': {u'priority': 0, u'redelivered': None, u'routing_key': u'celery', u'exchange': u'celery'}, u'hostname': u'celery@app.myplanmap.com', u'acknowledged': False, u'kwargs': u'{}', u'id': u'8ac59984-f8d0-47ae-ac9e-c4e3ea9c4ac6', u'worker_pid': None}}

仔细看一下,任务还没有被确认,所以在Celery重启后,它应该还留在Redis里,对吧?

相关文章:

  • 暂无相关问题
暂无标签

1 个回答

3

你应该用RabbitMQ,而不是Redis。

RabbitMQ功能齐全,稳定,耐用,而且安装起来很简单。它非常适合用在生产环境中。

Redis也功能齐全,但在突然关闭或停电的情况下,更容易丢失数据。

使用RabbitMQ后,你在重启时丢失消息的问题就能解决了。

撰写回答