但是,当我刚刚打开电脑并运行芹菜时,每隔50秒运行一次任务,我看到一些跳过,比如1小时。除了意外的跳过之外,它实际上执行得很好。为什么会这样?如何解决这个问题?
这是我的工作人员-l info
中跳过的日志的示例2016-11-03 10:13:36,264: INFO/MainProcess] Task core.tasks.sample[8efcedc5-1e08-41c4-80b9-1f82a9ddbaad] succeeded in 1.062010367s: None
[2016-11-03 11:14:19,751: INFO/MainProcess] Received task: core.tasks.sample[ca9d6ef4-2cdc-4546-a9fb-c413541a80ee]
以下是我的节拍-l信息
中跳过的日志的示例[2016-11-03 10:13:35,199: INFO/MainProcess] Scheduler: Sending due task core.tasks.sample (core.tasks.sample)
[2016-11-03 11:14:19,748: INFO/MainProcess] Scheduler: Sending due task core.tasks.sample (core.tasks.sample)
这是我的任务代码:
# 50 seconds
@periodic_task(run_every=timedelta(**settings.XXX_XML_PERIODIC_TASK))
def sample():
global GLOBAL_CURRENT_DATE
if cache.get('XXX_xml_today_saved_data') is None:
cache.set('XXX_xml_today_saved_data', [])
saved_data = cache.get('XXX_xml_today_saved_data')
ftp = FTP('xxxxx')
ftp.login(user='xxxxx', passwd='xxxxx')
ftp.cwd('XXX')
date_dir = GLOBAL_CURRENT_DATE.replace("-", "")
try:
ftp.cwd(date_dir)
except:
ftp.cwd(str(int(date_dir) - 1))
_str = StringIO()
files = ftp.nlst()
if (GLOBAL_CURRENT_DATE != datetime.now().strftime("%Y-%m-%d") and
files == saved_data):
GLOBAL_CURRENT_DATE = datetime.now().strftime("%Y-%m-%d")
cache.delete('XXX_xml_today_saved_data')
return
print files
print "-----"
print saved_data
unsaved = list(set(files) - set(saved_data))
print "-----"
print unsaved
if unsaved:
file = min(unsaved)
# modified_time = ftp.sendcmd('MDTM '+ file)
print file
ftp.retrbinary('RETR ' + file, _str.write)
xml = '<root>'
xml += _str.getvalue()
xml += '</root>'
if cache.get('XXX_provider_id') is None:
cache.set('XXX_provider_id', Provider.objects.get(code="XXX").id)
_id = cache.get('XXX_provider_id')
_dict = xmltodict.parse(xml, process_namespaces=True,
dict_constructor=dict, attr_prefix="")
row = _dict['root']['row']
if type(_dict['root']['row']) == dict:
_dict['root']['row'] = []
_dict['root']['row'].append(row)
row = _dict['root']['row']
for x in row:
if cache.get('XXX_data_type_' + x['dataType']) is None:
obj, created = DataType.objects.get_or_create(code=x['dataType'])
obj, created = ProviderDataType.objects.get_or_create(provider_id=_id, data_type=obj)
if created:
cache.set('XXX_data_type_' + x['dataType'], obj.id)
_id = cache.get('XXX_data_type_' + x['dataType'])
obj, created = Transaction.objects.get_or_create(data=x, file_name=file,
provider_data_type_id=_id)
if created:
if x['dataType'] == "BR":
print "Transact"
br_transfer(**x)
else:
print "Not transacting"
saved_data.append(file)
cache.set('XXX_xml_today_saved_data', saved_data)
ftp.close()
这是我在settings.py中的CELERY CONFIG:
BROKER_URL = 'redis://localhost:6379'
CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Africa/Nairobi'
XXX_XML_PERIODIC_TASK = {'seconds': 50}
CACHES = {
'default': {
'BACKEND': 'redis_cache.RedisCache',
'LOCATION': 'localhost:6379',
'TIMEOUT': None,
},
}
有任何解释或建议吗?
我正在使用python 2.7.10和django 1.10
答案 0 :(得分:1)
Celery工作人员在准备就绪时从队列中弹出任务,但如果任务有倒计时,它将同时弹出其他任务并等待时间过期做其他事情。它不保证任务将在那时运行,至少在那个时间或之后运行。
答案 1 :(得分:1)
可能会有一些问题。最有可能的是,当您的任务被触发时,您的工作人员很忙。你可以通过增加工人来防止这种情况。 docs解释了单个worker的--concurrency
选项,以及运行多个worker进程的选项。
您还可以运行附加到不同项目的不同工作人员,以便将某些任务分配给某些项目。即,某些任务的专用队列:Starting worker with dynamic routing_key?
我还看到,工作人员可以预取任务并抓住他们 - 但如果当前正在运行的任务超过倒计时,您的任务可能会延迟。
您想阅读CELERYD_PREFETCH_MULTIPLIER
: