celery 时间不同步求破,导致 soft_time_limit 失效 [V 币感谢]

2019-01-09 08:49:28 +08:00
 akmonde

RT,客户端和服务端应该已经实行了 NTP 同步:

# service ntp restart
# ntpdate pool.ntp.org
 9 Jan 08:28:19 ntpdate[8247]: the NTP socket is in use, exiting

Server 和 client 端的相关配置:

CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_ENABLE_UTC = False
#这里标识下,CELERY_ENABLE_UTC True 和 False 都试过了,没用

本地 worker 运行时的时间:

celery -A test worker -E -l INFO -n hostA --concurrency=2
[2019-01-09 08:29:04,904: INFO/MainProcess]

server 端运行 flower 时,命令行显示的时间:

celery -A test flower --port=5555

[W 190109 08:29:04 state:122] Substantial drift from celery@test may mean clocks are out of sync.  Current drift is 57600 seconds.  [orig: 2019-01-09 08:29:04.870091 recv: 2019-01-10 00:29:04.931890]

然鹅,在 flower 的 web 界面上,显示我某个卡住的任务是在 57600s 后的未来接受的任务,然后就一直 starting 卡在那儿了。 后来 Ctrl+c 才开始执行,报了个 broker 超时重连,然后把这个卡住的任务跑完了,才停止。 其实这里也没搞明白为啥。

我猜测是因为这个任务开始时间超过了我任务,我的 soft_time_limit 也没有起作用。

求解,如何同步 server 端收到的时间,希望不再有时差,找了很久没有解决。

很急,在线等大佬!

3679 次点击
所在节点    Python
10 条回复
arrow8899
2019-01-09 09:30:21 +08:00
celery 的时区 BUG 好像一直都存在,还没有修复

https://github.com/celery/django-celery-beat/issues/80#issuecomment-373615356

celery.py
```
app = Celery('test')
app.now = datetime.now # 关键在这里
```

settings.py
```
CELERY_TIMEZONE = 'Asia/Shanghai'
DJANGO_CELERY_BEAT_TZ_AWARE = False
CELERY_ENABLE_UTC = False
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
```
akmonde
2019-01-09 09:54:42 +08:00
@arrow8899 刚才试了,好像还是不管用...
akmonde
2019-01-09 12:02:48 +08:00
@arrow8899 我把 celery 升级到 3.1.7 解决了,小版本升级太烦人。
fanhaipeng0403
2019-01-09 13:02:07 +08:00
设置个环境变量 export TZ = = 'Asia/Shanghai'

为啥不直接升到 4
akmonde
2019-01-09 13:15:53 +08:00
@fanhaipeng0403
@arrow8899
抱歉,乌龙了,好像不是版本的原因。
我原来的是 3.1.25 ,改成了 3.1.7,先是成功了一下,后来发现 worker 好像一直 offline。
连着切了几个版本都这样,我后来又换回 3.1.25 ,莫名其妙暂时没有问题了,暂时还没跑偏。
我本来环境变量就是 shanghai,这个我确定。
我晚点再测测,还没找出啥原因。
我曾在这里测过:
>>> from celery.utils.timeutils import utcoffset
>>> utcoffset()
worker 和 client,一个 8,一个 8,刚好是相差 57600s。
现在莫名其妙两个都变成-8 了。
akmonde
2019-01-09 13:19:26 +08:00
@fanhaipeng0403
忘了回复您另一个问题,我这边需要用到 3.x 版本以上废弃的一个功能,也就是使用 test.delay()调用 chord 聚合执行,所以不能升级太高。
lolizeppelin
2019-01-09 14:17:12 +08:00
稍微读下时间获取部分源码就知道了 还能有莫名其妙的

还有, 时间同步把 ntp 服务开了不要跑 ntpdate
akmonde
2019-01-09 16:20:08 +08:00
@lolizeppelin Grep 了 ntpdate,进程好像后台没有跑 ntpdate,就执行了一次。
唉,紧急处理,没想到去读源码,实在心急看不下去。
lolizeppelin
2019-01-09 17:57:40 +08:00
ntp 服务和 ntpdate 是不同的

系统有有相关代码来调整时间的 ntpdate 是属于强制改时间的

有可能触发时间回退 导致定时器重复触发

不要用 ntpdate 来调时间!!!!

python 时间本来就比较简单,怎么封装也不会复杂 随便读一下就知道 Celery 怎么获取时间的了
又不是要你去读 system call
akmonde
2019-01-09 18:06:07 +08:00
@lolizeppelin 受教,下次注意。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/525224

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX