我将我的Django项目(从celery==2.5.5
和django-celery==2.5.5
)更新为celery==3.0.7
和django-celery==3.0.6
。然后发生了奇怪的事情。
我注意到的第一件事是Django Celery Admin界面中的每个日期/时间都被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:00
或2012-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更新后,我删除了所有数据库表并生成了syncdb
我的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_UTC
或CELERY_TIMEZONE
修改:celery==3.0.9
和django-celery==3.0.9
编辑:顺便提一句celeryev
显示正确的日期时间(我假设为GMT)
编辑:我使用PostgreSQL数据库
答案 0 :(得分:3)
似乎这应该在新版本中修复,并建议临时解决方法分支3.0 https://github.com/celery/django-celery/issues/183#issuecomment-10846821。
答案 1 :(得分:0)
至少根据release notes,时区错误修正了.0.8和.0.9。
使用芹菜3.09和django-celery 3.0.9
答案 2 :(得分:0)
如果你(像我一样)得到
,也会出现这个问题TIME_ZONE = 'UTC'
...
CELERY_TIMEZONE = 'Europe/Moscow'
Django settings.py
中的。这两个字符串可以位于此大settings.py
个配置文件的不同部分,在这种情况下,Celery beat(例如)会显示时区已更改的消息。类似的东西:Timezone changed from 'UTC' to 'Europe/Moscow'
但你会看到的实际节拍时间仍然是UTC。要修复它,只需设置正确的Django TIME_ZONE
设置:
TIME_ZONE = 'Europe/Moscow'
芹菜会把它拿起来!
干杯。