项目中有使用到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 去执行,结果呢
当requtc为True时,执行to_system_tz方法转换eta,否则直接使用Celery设置的时区转换,这个requtc又是什么?
从这里可以看出,当我们设置了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必须要包含时区信息,之前并没有注意到
这个其实可以算Redis的问题。
使用 type 命令查看对应的数据类型,再使用其他命令查看内容
> type $key
例如对于最基本的键值,使用 get $key 即可。对于 list ,使用 lrange (由于是拿一个范围,需要先用 llen 获取长度作为参数)。
当然,在Python下调用Redis客户端的相关命令也是可以实现的。
以上就是关于mac 电脑有哪些网页的抓取工具全部的内容,包括:mac 电脑有哪些网页的抓取工具、CELERY 定时任务、如何用 Python 构建一个简单的分布式系统等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)