celery worker 的任务 运行,主管获取 datetime.date.today() 的错误值
Task run by celery worker with supervisor getting incorrect value for datetime.date.today()
我有一项任务 运行 定期使用 celery beat。 celery beat 和 celery worker(在单独的队列中)都运行正在使用主管。
任务正在使用 python 的 datetime.date.today()
函数存储 运行 日期。
问题是 datetime.date.today()
returns 工人重新启动的正确日期,但在接下来的几天使用 celery beat 调用同一任务时,datetime.date.today()
函数 returns 相同的日期当工作人员重新启动而不是当前日期时。
任务 运行ning 在 utc 时区,我交叉检查了执行日期。当我尝试使用 celery beat 将 运行 日期作为 args
传递时,也会发生同样的情况(在这种情况下,它返回 celery beat 的 start/restart 日期而不是当前日期)。
我仍然不明白为什么会这样。服务器系统日期/时间似乎工作正常。
这是 celery beat 和 celery worker 队列的主管配置(这不是完整的配置,只是相关的块)
[supervisord]
logfile=/dir/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trac
pidfile=supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024
minprocs=200 ; (min. avail process descriptors;default 200)
[program:celery_worker_custom_queue]
environment =
LC_ALL=en_US.UTF-8,
LANG=en_US.UTF-8
command = /usr/local/bin/celery --concurrency=5 -A config worker -l info -Q custom_queue -n workername@%%h
directory = /path/to/dir
priority = 2
user = user
numprocs = numprocs
stderr_logfile = log_file_path
stdout_logfile = log_file_path
autostart = true
autorestart = true
[program:celery_beat]
environment =
LC_ALL=en_US.UTF-8,
LANG=en_US.UTF-8
command = /usr/local/bin/celery -A config beat -l info
directory = /path/to/dir
priority = 3
user = user
numprocs = numprocs
stderr_logfile = log_file_path
stdout_logfile = log_file_path
autostart = true
autorestart = true
我在网上查了下也没有发现类似的问题。另外,我不能撤掉主管。
我可以在配置中做些什么吗?另外,我是第一次使用这样的设置,我在概念上是否遗漏了什么?请帮忙
编辑:
我已经在我的本地机器上对此进行了测试,它 运行 在没有主管的情况下正常运行。任务代码如下(去掉运行日期不使用的代码)
import datetime as dt
run_date = (dt.date.today()).strftime('%Y-%m-%d')
@celeryApp.task(bind=True, name="api_task",queue="custom_queue")
def api_task(self, start_date=run_date):
api_run_date = start_date
#api calls and object calculations; api_run_date is not used anywhere..
task_status(obj=status_obj, status=True, run_date=api_run_date)
def task_status(obj, status=False, run_date=run_date):
is_done = status
# print(obj,' - ',run_date,' - ',is_done)
done, created = ModelName.objects.update_or_create(date=run_date, defaults={'is_done': is_done}, obj_inst=obj)
done.save()
我认为问题在于您处理日期的方式。您将 datetime.date.today()
值存储在 run_date
全局变量中,然后将其用作任务的 start_date
参数的默认值。但是当函数在 Python 中定义时,默认参数值只计算一次。因此,除非您在调用 api_task
时实际为 start_date
提供值,否则您始终使用相同的值。该值是 run_date
全局变量的值,在首次导入模块时仅计算一次。
正确的处理方式是这样的:
def api_task(self, start_date=None):
# use `start_date` if given or current date
api_run_date = start_date or dt.date.today().strftime('%Y-%m-%d')
#api calls and object calculations; api_run_date is not used anywhere..
task_status(obj=status_obj, status=True, run_date=api_run_date)
我有一项任务 运行 定期使用 celery beat。 celery beat 和 celery worker(在单独的队列中)都运行正在使用主管。
任务正在使用 python 的 datetime.date.today()
函数存储 运行 日期。
问题是 datetime.date.today()
returns 工人重新启动的正确日期,但在接下来的几天使用 celery beat 调用同一任务时,datetime.date.today()
函数 returns 相同的日期当工作人员重新启动而不是当前日期时。
任务 运行ning 在 utc 时区,我交叉检查了执行日期。当我尝试使用 celery beat 将 运行 日期作为 args
传递时,也会发生同样的情况(在这种情况下,它返回 celery beat 的 start/restart 日期而不是当前日期)。
我仍然不明白为什么会这样。服务器系统日期/时间似乎工作正常。
这是 celery beat 和 celery worker 队列的主管配置(这不是完整的配置,只是相关的块)
[supervisord]
logfile=/dir/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trac
pidfile=supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024
minprocs=200 ; (min. avail process descriptors;default 200)
[program:celery_worker_custom_queue]
environment =
LC_ALL=en_US.UTF-8,
LANG=en_US.UTF-8
command = /usr/local/bin/celery --concurrency=5 -A config worker -l info -Q custom_queue -n workername@%%h
directory = /path/to/dir
priority = 2
user = user
numprocs = numprocs
stderr_logfile = log_file_path
stdout_logfile = log_file_path
autostart = true
autorestart = true
[program:celery_beat]
environment =
LC_ALL=en_US.UTF-8,
LANG=en_US.UTF-8
command = /usr/local/bin/celery -A config beat -l info
directory = /path/to/dir
priority = 3
user = user
numprocs = numprocs
stderr_logfile = log_file_path
stdout_logfile = log_file_path
autostart = true
autorestart = true
我在网上查了下也没有发现类似的问题。另外,我不能撤掉主管。
我可以在配置中做些什么吗?另外,我是第一次使用这样的设置,我在概念上是否遗漏了什么?请帮忙
编辑: 我已经在我的本地机器上对此进行了测试,它 运行 在没有主管的情况下正常运行。任务代码如下(去掉运行日期不使用的代码)
import datetime as dt
run_date = (dt.date.today()).strftime('%Y-%m-%d')
@celeryApp.task(bind=True, name="api_task",queue="custom_queue")
def api_task(self, start_date=run_date):
api_run_date = start_date
#api calls and object calculations; api_run_date is not used anywhere..
task_status(obj=status_obj, status=True, run_date=api_run_date)
def task_status(obj, status=False, run_date=run_date):
is_done = status
# print(obj,' - ',run_date,' - ',is_done)
done, created = ModelName.objects.update_or_create(date=run_date, defaults={'is_done': is_done}, obj_inst=obj)
done.save()
我认为问题在于您处理日期的方式。您将 datetime.date.today()
值存储在 run_date
全局变量中,然后将其用作任务的 start_date
参数的默认值。但是当函数在 Python 中定义时,默认参数值只计算一次。因此,除非您在调用 api_task
时实际为 start_date
提供值,否则您始终使用相同的值。该值是 run_date
全局变量的值,在首次导入模块时仅计算一次。
正确的处理方式是这样的:
def api_task(self, start_date=None):
# use `start_date` if given or current date
api_run_date = start_date or dt.date.today().strftime('%Y-%m-%d')
#api calls and object calculations; api_run_date is not used anywhere..
task_status(obj=status_obj, status=True, run_date=api_run_date)