【问题标题】:Celery task with a time_start attribute in 19701970 年具有 time_start 属性的 Celery 任务
【发布时间】:2013-12-04 04:24:43
【问题描述】:

对当前正在运行的 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}]}

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

>> from datetime import datetime
>> datetime.fromtimestamp(9636801.218162088)
datetime.datetime(1970, 4, 22, 13, 53, 21, 218162)

我是否误解了time_task 属性?我的 Celery 应用是否配置错误?

我在 Linux 上使用 Celery 3.1.4 与 Django 应用程序和 Redis 后端。

任务由一个worker运行,执行如下:

./manage.py celery worker --loglevel=INFO --soft-time-limit=600 --logfile=/tmp/w1.log --pidfile=/tmp/w1.pid -n 'w1.%%h'

【问题讨论】:

  • 感谢您的关注!我添加了一些细节。
  • 下一个问题:你的操作系统是什么?是所有任务都具有如此奇怪的 start_times 还是只有其中一些?以及您在有工人的机器上的日期值是多少?
  • 时间戳不是UNIX时间戳,它使用的是time.monotonic(),所以在进程外可能没有用(取决于单调的实现)

标签: python django redis celery celery-task


【解决方案1】:

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

正如clock_gettimedocumentation 中所解释的,这个单调时间表示“从某个未指定的起点开始”经过的时间。此函数的目的是确保时间单调增加,尽管其他时钟值发生变化。

因此,为了获得任务开始的真实日期时间,我们只需要将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)

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

【讨论】:

  • 在阅读您的答案之前不应发表评论:) 请注意,单调时间仅在同一台机器上有用。如果您需要,我们可以在检查输出中提供参考时间戳(您可以在 celery github 问题跟踪器上打开功能请求)
  • 那太好了!我会这样做的。
  • 这工作得很好,直到你有不止一台机器运行 celery。当这种情况发生时,当前机器的monotonic 并不是每个任务都适合。
  • 每次我回到这个答案时,我都会因为没有做 PR 而感到难过...@asksol 那仍然有意义吗?
  • @RégisB。这次真是万分感谢。您现在能否澄清一下,在修复之后,time_start 的具体措施是什么?你相信我在任何地方的文档中都找不到这个吗?这现在只是time.time() 返回的纪元时间吗?这可以与time.time() 进行比较以获得时间增量(自开始以来经过的时间)?有没有一种方便的方法可以将time_start 呈现为当地时间?
猜你喜欢
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-04
  • 2019-08-23
  • 1970-01-01
  • 2018-11-28
相关资源
最近更新 更多