最佳实践:Tips and Best Practices

忽略不想要的结果

如果你并不关心任务的结果,请务必确定设置 ignore_result 选项,因为存储结果会浪费时间和资源。
1
@app.task(ignore_result=True)
2
def mytask():
3
something()
Copied!
可以使用 task_ignore_result 配置全局禁用结果。
在调用apply_asyncdelay执行任务时, 通过传递ignore_result参数, 可以在每次执行的基础上设置开启/禁用任务结果。
1
@app.task
2
def mytask(x, y):
3
return x + y
4
5
# No result will be stored
6
result = mytask.apply_async(1, 2, ignore_result=True)
7
print result.get() # -> None
8
9
# Result will be stored
10
result = mytask.apply_async(1, 2, ignore_result=False)
11
print result.get() # -> 3
Copied!
默认情况下, 当配置了 backend ,任务将不会忽略结果( ignore_result=False )
选项优先顺序如下(从低到高):
  • 1.全局选项task_ignore_result
  • 2.任务配置ignore_result
  • 3.任务执行时选项ignore_result

更多的优化技巧

您可以在优化: Optimizing中找到其他的优化技巧。

避免启动同步子任务

让一个任务等待另一个任务的结果往往是非常低效的,并在工作池耗尽时,可能会导致死锁。
建议使您的设计异步化,例如使用回调函数。
糟糕的使用:
1
@app.task
2
def update_page_info(url):
3
page = fetch_page.delay(url).get()
4
info = parse_page.delay(url, page).get()
5
store_page_info.delay(url, info)
6
7
@app.task
8
def fetch_page(url):
9
return myhttplib.get(url)
10
11
@app.task
12
def parse_page(url, page):
13
return myparser.parse_document(page)
14
15
@app.task
16
def store_page_info(url, info):
17
return PageInfo.objects.create(url, info)
Copied!
较好的使用:
1
def update_page_info(url):
2
# fetch_page -> parse_page -> store_page
3
chain = fetch_page.s(url) | parse_page.s() | store_page_info.s(url)
4
chain()
5
6
@app.task()
7
def fetch_page(url):
8
return myhttplib.get(url)
9
10
@app.task()
11
def parse_page(page):
12
return myparser.parse_document(page)
13
14
@app.task(ignore_result=True)
15
def store_page_info(info, url):
16
PageInfo.objects.create(url=url, info=info)
Copied!
将不同任务的signature进行链接,组成任务链来达成目的。您可以在Canvas: 设计工作流程中了解任务链和其他强大的结构。
默认情况下,Celery不允许您在任务中运行同步子任务,但是在极少数或极端情况下您可能需要这么做。警告:强烈不建议在任务中运行同步子任务。
任务中强制运行同步子任务:
1
@app.task
2
def update_page_info(url):
3
page = fetch_page.delay(url).get(disable_sync_subtasks=False)
4
info = parse_page.delay(url, page).get(disable_sync_subtasks=False)
5
store_page_info.delay(url, info)
6
7
@app.task
8
def fetch_page(url):
9
return myhttplib.get(url)
10
11
@app.task
12
def parse_page(url, page):
13
return myparser.parse_document(page)
14
15
@app.task
16
def store_page_info(url, info):
17
return PageInfo.objects.create(url, info)
Copied!