Celery任务在1970年具有time_start属性

Rég*_* B. 21 python django redis celery celery-task

检查当前运行的Celery任务会发现一个奇怪的time_start时间戳:

>> celery.app.control.inspect().active()
{u'celery@worker.hostname': [{u'acknowledged': True,
   u'args': u'(...,)',
   u'delivery_info': {u'exchange': u'celery',
    u'priority': 0,
    u'redelivered': None,
    u'routing_key': u'celery'},
   u'hostname': u'celery@worker.hostname',
   u'id': u'3d92fdfd-524e-4ba1-98cb-cf83af2ad8e9',
   u'kwargs': u'{}',
   u'name': u'task_name',
   u'time_start': 9636801.218162088,
   u'worker_pid': 7931}]}
Run Code Online (Sandbox Code Playgroud)

time_start属性将任务追溯到1970年(那是在创建Celery,Python之前,我没有自定义的DeLorean):

>> from datetime import datetime
>> datetime.fromtimestamp(9636801.218162088)
datetime.datetime(1970, 4, 22, 13, 53, 21, 218162)
Run Code Online (Sandbox Code Playgroud)

我是否误解了这个time_task属性?我的Celery应用程序配置错误了吗?

我在Linux上使用带有Django应用程序和Redis后端的Celery 3.1.4.

任务由执行的工作程序运行,如下所示:

./manage.py celery worker --loglevel=INFO --soft-time-limit=600 --logfile=/tmp/w1.log --pidfile=/tmp/w1.pid -n 'w1.%%h'
Run Code Online (Sandbox Code Playgroud)

Rég*_* B. 31

我通过挖掘Celery和Kombu代码找到了我自己问题的答案:time_start任务的属性由kombu.five.monotonic函数计算.(讽刺的是,海带代码还指另一StackOverflow的问题供参考)由该函数返回的时间戳是指"单调"的时间由所计算的clock_gettime系统调用.

正如clock_gettime 文档中所解释的,这个单调时间代表"从一些未指定的起点开始"所经过的时间.此功能的目的是确保时间单调增加,尽管其他时钟值发生变化.

因此,为了获得任务开始的实际日期时间,我们只需要将time_start属性与单调时钟的当前值进行比较:

>> from datetime import datetime
>> from time import time
>> import kombu.five
>> datetime.fromtimestamp(time() - (kombu.five.monotonic() - 9636801.218162088))
datetime.datetime(2013, 11, 20, 9, 55, 56, 193768)
Run Code Online (Sandbox Code Playgroud)

编辑:time_start检查报告的属性不再单调:https://github.com/celery/celery/pull/3684我花了四年时间才写出正确的拉取请求0 :-)

  • 这个工作非常好,直到你有多台机器运行芹菜.当发生这种情况时,当前机器的"​​单调"对于每个任务来说都不是正确的. (4认同)