celery时区设置问题源码探究

author author     2023-03-23     117

关键词:

参考技术A

项目中有使用到Celery框架,主要使用Celery来在使用Django搭建的项目中创建延时任务及周期任务。在使用过程中出现过延时任务及周期任务到预定时间未能执行的情况。Google、百度了一些网友的分析及解决方案,大多认为是Celery时区设置导致的问题。然而这些解答大多类似,而且并不能解决我心中的疑惑,因此决定研究源码一探究竟。

这里网上大多数解答存在问题的地方,将延时任务及周期任务混为一谈了。周期任务是存在一个周期,定时执行的任务,类似Linux系统的Crontab定时任务。而延时任务更类似一个普通的异步任务,不同的是存在一个ETA延时时间,这种任务只会执行一次。因此我们会分开讨论两种任务。

celery存在两个时区的配置 enable_utc timezone ,前者表示是否使用UTC时间,后者表示celery使用的时区。celery默认使用UTC时间,若使用默认配置,则celery设置周期任务时,必须使用UTC时间,比如

当系统时间是北京时间时,这样的设置会导致这个任务并不会在每天北京时间9:30执行,而是17:30,因为UTC时间和北京时间相差8小时。因此这里我们将配置修改为

这样周期任务就能正常执行了

大多数网上的解答止步于上述的结果,认为上述设置之后,延时任务就同样没有任何问题了,其实不然,例如

我们准备让这个任务在 2021-08-19 18:10:30 去执行,结果呢

当req.utc为True时,执行to_system_tz方法转换eta,否则直接使用Celery设置的时区转换,这个req.utc又是什么?

从这里可以看出,当我们设置了args参数时,由hybrid_to_proto2返回,继续

omg!!!原来apply_async方法还有一个参数叫utc吗,而且默认值是True,看文档的时候并没有注意到!到这里,我们大概能看出问题的所在了,延时任务也可以认为普通的异步任务,存在自己的时区配置参数,之前提到的enable_utc并不能影响到这里。我们再看看传入的eta做了哪些处理。

传入的native类型的时间,居然直接被转换成UTC时间了!!!

讨论了这么多,我们能得出最终解决Celery时区问题的结论
1、对于周期任务,需要将celery的配置enable_utc设置成False,timezone设置成系统当前的时区
2、对于延时任务,如果需要设置eta,即精确在某一时间执行,则这个eta必须包含时区信息

最终结论相当简单,但是花了大量时间去研究了源码。对于延时任务eta设置曾经也是相当困惑,其实对于官方文档确实有提到,eta必须要包含时区信息,之前并没有注意到

在每个时区每天凌晨 3:00 运行 celery 任务?姜戈

】在每个时区每天凌晨3:00运行celery任务?姜戈【英文标题】:Runcelerytaskeverydayat3:00amineverytimezone?Django【发布时间】:2021-10-0207:12:48【问题描述】:我需要在每天凌晨3:00为多个时区运行一项任务,在应用中每个组织都有一个时区... 查看详情

celery学习(代码片段)

1、安装django-celery、celery、django-redis等一系列package2、setting.py设置:djcelery.setup_loader()BROKER_URL=‘redis://127.0.0.1:6379/0‘CELERY_TIMEZONE=‘Asia/Shanghai‘#并没有北京时区,与下面TIME_ZONE应该一致CELERYBEAT_SCHEDULER= 查看详情

celery源码解析四:定时任务的实现

在系列中的第二篇我们已经看过了Celery中的执行引擎是如何执行任务的,并且在第三篇中也介绍了任务的对象,但是,目前我们看到的都是被动的任务执行,也就是说目前执行的任务都是第三方调用发送过来的。可能你会有点奇... 查看详情

python神器celery源码解析

Celery是一款非常简单、灵活、可靠的分布式系统,可用于处理大量消息,并且提供了一整套操作此系统的工具。Celery也是一款消息队列工具,可用于处理实时数据以及任务调度。本文是是celery源码解析的第四篇,... 查看详情

python神器celery源码解析(代码片段)

Celery是一款非常简单、灵活、可靠的分布式系统,可用于处理大量消息,并且提供了一整套操作此系统的工具。Celery也是一款消息队列工具,可用于处理实时数据以及任务调度。本文是是celery源码解析的第五篇,... 查看详情

django redis celery 和 celery beats 的正确设置

】djangorediscelery和celerybeats的正确设置【英文标题】:Correctsetupofdjangoredisceleryandcelerybeats【发布时间】:2018-07-1321:50:45【问题描述】:我一直在尝试设置django+celery+redis+celery_beats,但这给我带来了麻烦。文档非常简单,但是当我运... 查看详情

python神器celery源码解析:不同启动模式的分析(代码片段)

剧照| 《鬼灭之刃·游郭篇》Celery是一款非常简单、灵活、可靠的分布式系统,可用于处理大量消息,并且提供了一整套操作此系统的工具。Celery也是一款消息队列工具,可用于处理实时数据以及任务调度。本文是是c... 查看详情

celery-django 找不到设置

】celery-django找不到设置【英文标题】:celery-djangocan\'tfindsettings【发布时间】:2011-03-2009:12:25【问题描述】:我有一个Django项目,它使用Celery来运行异步任务。我正在WindowsXP机器上进行开发。启动我的Django服务器(pythonmanage.pyrunser... 查看详情

springboot:web开发静态资源源码探究

...目之后,深刻了解自动配置原理(重点)之后,还有很多问题需要我们解决,学过SSM的都只有springmvc和mybatis都得放入spring容器中,springboot也一样   在我们原生项目的resources下会有static这个文件夹,但远远不止这个能... 查看详情

python神器celery源码解析(代码片段)

△点击上方“Python猫”关注,回复“1”领取电子书Celery是一款非常简单、灵活、可靠的分布式系统,可用于处理大量消息,并且提供了一整套操作此系统的工具。Celery也是一款消息队列工具,可用于处理实时数据... 查看详情

芹菜没有选择 CELERY_ALWAYS_EAGER 设置

】芹菜没有选择CELERY_ALWAYS_EAGER设置【英文标题】:CelerynotpickingCELERY_ALWAYS_EAGERsettings【发布时间】:2017-10-1111:53:40【问题描述】:我正在运行Django1.8+Celery4.0.2Celery配置良好,可以在redis后端本地运行我的Django任务。但是当我尝试... 查看详情

为啥jenkins设置了定时构建但没触发?

...后,还是未生效有时候jenkins在linux下部署的话,就会存在时区问题一说,jenkins构建在启动时加入time-zone时区可以解决,但在周期构建时,特别要注意时区并转换,如下图写完后,jenkins会提示什么时候运行,这时要注意些的是什... 查看详情

django的时区设置问题(代码片段)

1.Django的时区问题  django默认的时区是UTC,平时是没有什么影响的,但是在需要将时间戳转换成本时区的时间或者是获取当前的本地的localtime的时候就出现了问题。之前程序在测试时是运行在Windows环境,所以即使settings.py中的T... 查看详情

最近在做celery时报mysqlbackenddoesnotsupporttimezone-awaredatetimeswhenuse_tzisfalse.错误(代码片段)

当setting.py中的CELERY_TIMEZONE设置的是非UTC的话,比如说’Asia/Shanghai’,且USE_TZ设置为False的话,那么启动定时任务的时候会报错,报错信息如下: raiseValueError("MySQLbackenddoesnotsupporttimezone-awaredatetimeswhenUSE_TZisF... 查看详情

redis事务相关源码探究(代码片段)

...CLIENT_MULTI)addReplyError(c,"MULTIcallscannotbenested");return; //设置事务标识c->flags|=CLIENT_MULTI;addReply(c,shared.ok);1、首先会判断当前客户端是是否已经开启了事务,Redis中的事务不支持嵌套;2、给flags设置事务标识CLIENT_MULTI... 查看详情

在使用 django_celery_beat 设置的 Django 视图中使用 Celery 定期任务输出,并使用 Redis 设置缓存

】在使用django_celery_beat设置的Django视图中使用Celery定期任务输出,并使用Redis设置缓存【英文标题】:UseCeleryperiodictasksoutputinDjangoviewssetupwithdjango_celery_beatandCachinewithRedis【发布时间】:2020-10-2601:26:12【问题描述】:我正在尝试使... 查看详情

django + celery - 如何在我的 django 应用程序中为 celery 设置 crontab 计划?

】django+celery-如何在我的django应用程序中为celery设置crontab计划?【英文标题】:django+celery-HowdoIsetupacrontabscheduleforceleryinmydjangoapp?【发布时间】:2014-07-1801:08:43【问题描述】:我正在按照这里的说明进行操作:http://celery.readthedocs.... 查看详情

以 root 身份运行 Celery

】以root身份运行Celery【英文标题】:RunningCeleryasroot【发布时间】:2013-12-1906:09:08【问题描述】:出于访问原因,我需要以root身份运行我的Django和Celery。它说我需要设置C_FORCE_ROOT环境变量。如何/在哪里设置环境变量?【问题讨... 查看详情