【问题标题】:Django Celery Timezone misconfiguration or bugDjango Celery 时区配置错误或错误
【发布时间】:2012-09-10 16:54:17
【问题描述】:

我将我的 Django 项目(从 celery==2.5.5django-celery==2.5.5)更新为 celery==3.0.7django-celery==3.0.6。然后奇怪的事情发生了。

我注意到的第一件事是 Django Celery 管理界面中的每个日期/时间都偏移了 3 个小时。因为我的TIME_ZONE = 'Europe/Sofia' 现在是UTC/GMT +3 小时,所以我认为问题与时区有关。

我查看了 celerycam 日志并找到了这个

UPDATE "djcelery_workerstate" SET "hostname" = 'three', "last_heartbeat" = '2012-09-18 17:57:49.000701+03:00' WHERE "djcelery_workerstate"."id" = 1 ; args=(u'three', u'2012-09-18 17:57:49.000701+03:00', 1)

last_heartbeat 不正确,它必须是 2012-09-18 14:57:49.000701+03:002012-09-18 11:57:49.000701+00:00

也许某些函数期望日期时间不感知时区,但传递的日期时间实际上是时区感知。

CeleryCam 日志中的错误也证实了我的想法,该错误仅在重试任务时发生!该任务有这个@task(default_retry_delay = 30, max_retries = 60) 装饰器。

这是错误:

[2012-09-18 14:46:54,001: ERROR/MainProcess] Error in timer: ValueError('Not naive datetime (tzinfo is already set)',)
Traceback (most recent call last):
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/celery/utils/timer2.py", line 92, in apply_entry entry()
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/celery/utils/timer2.py", line 48, in __call__ return self.fun(*self.args, **self.kwargs)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/celery/utils/timer2.py", line 149, in _reschedules return fun(*args, **kwargs)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/celery/events/snapshot.py", line 71, in capture self.state.freeze_while(self.shutter, clear_after=self.clear_after)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/celery/events/state.py", line 225, in freeze_while return fun(*args, **kwargs)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/celery/events/snapshot.py", line 68, in shutter self.on_shutter(self.state)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/django/db/transaction.py", line 209, in inner return func(*args, **kwargs)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/djcelery/snapshot.py", line 139, in on_shutter self._autocommit(_handle_tasks)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/djcelery/snapshot.py", line 115, in _autocommit fun()
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/djcelery/snapshot.py", line 133, in _handle_tasks self.handle_task(task)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/djcelery/snapshot.py", line 74, in handle_task "eta": maybe_make_aware(maybe_iso8601(task.eta)),
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/djcelery/utils.py", line 74, in maybe_make_aware return make_aware(value)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/djcelery/utils.py", line 52, in make_aware value = timezone.make_aware(value, timezone.utc)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/django/utils/timezone.py", line 269, in make_aware return timezone.localize(value, is_dst=None)
  File "/opt/pythonenv/TICKETS/local/lib/python2.7/site-packages/pytz/__init__.py", line 231, in localize raise ValueError('Not naive datetime (tzinfo is already set)')
ValueError: Not naive datetime (tzinfo is already set)

在 Django/Celery 更新后,我删除了所有数据库表并制作了同步数据库

我的 Django 项目的时区设置是:

TIME_ZONE = 'Europe/Sofia'
USE_TZ = True

Django/Celery 设置为:

# RabbitMQ Broker
BROKER_HOST                = 'localhost'
BROKER_PORT                = 5672
BROKER_VHOST               = 'tixgate'
BROKER_USER                = 'tixgate'
BROKER_PASSWORD            = '*******'

# Redis Result Backend
CELERY_RESULT_BACKEND      = 'redis'
CELERY_REDIS_HOST          = 'localhost'
CELERY_REDIS_PORT          = 6379
CELERY_REDIS_DB            = 4
CELERY_REDIS_PASSWORD      = '*******'

CELERY_SEND_EVENTS         = True
CELERY_TASK_RESULT_EXPIRES = 60 * 60 * 24 # 1 day
CELERY_ALWAYS_EAGER        = False

而且我没有明确设置CELERY_ENABLE_UTCCELERY_TIMEZONE

编辑:celery==3.0.9django-celery==3.0.9 的问题仍然存在

编辑:顺便说一下,celeryev 显示了正确的日期时间(我假设是 GMT)

编辑:我使用 PostgreSQL 数据库

【问题讨论】:

    标签: django timezone celery django-celery


    【解决方案1】:

    如果你(和我一样)得到这个问题也会出现

    TIME_ZONE = 'UTC'
    
    ...
    
    CELERY_TIMEZONE = 'Europe/Moscow'
    

    在 Django 中settings.py。这 2 个字符串可以位于这个大的 settings.py 配置文件的不同部分,在这种情况下,Celery beat(例如)将向您显示时区已更改的消息。类似的东西:Timezone changed from 'UTC' to 'Europe/Moscow' 但您将看到的真实节拍时间仍将是 UTC。要修复它,只需设置正确的 Django TIME_ZONE 设置:

    TIME_ZONE = 'Europe/Moscow'
    

    Celery 会捡起来的!

    干杯。

    【讨论】:

      【解决方案2】:

      似乎这应该在新版本中修复,作为临时解决方法分支 3.0 建议 https://github.com/celery/django-celery/issues/183#issuecomment-10846821

      【讨论】:

        【解决方案3】:

        至少根据release notes,时区错误已在.0.8 和.0.9 中修复。

        使用 celery 3.09 和 django-celery 3.0.9

        【讨论】:

        • 3.0.9 版本问题依然存在 :(
        • 您是否按照发行说明中的​​说明进行操作?还有一些额外的步骤需要采取
        • 我看到了它们,但它们并不相关,它们只是修复不再使用的旧记录。我对新开始的任务也有同样的问题
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2017-04-14
        • 2016-11-03
        • 2013-04-12
        • 2020-12-25
        相关资源
        最近更新 更多