有時候我們需要花費長時間運行某個任務(如:發送短信,發送郵件),我們可以不必在用戶的請求中等待任務結束,那么可以使用任務隊列發送必須的數據給另一個進程。這樣就可以在后臺運行任務,立即返回請求。
Celery 是強大的任務隊列庫,它可以用于簡單的后臺任務,也可用于復雜的多階段應用的計劃。
安裝依賴
```
(.venv) root@airvip:~/python_app/flask-demo# pip install celery
```
我們單獨創建一個文件夾存放我們的任務隊列,在 `app` 目錄下新建 `tasks` 目錄
```
root@airvip:~/python_app/flask-demo/app# pwd
/root/python_app/flask-demo/app
root@airvip:~/python_app/flask-demo/app# mkdir tasks
root@airvip:~/python_app/flask-demo/app#
```
我們選用 redis 作為我們的消息中間件,celery 也支持 **RabbitMQ**,**Amazon SQS**,**Zookeeper**
在 `app/tasks` 目錄下新建 `__init__.py` , `config.py`文件以及 `compute` 目錄
`config.py` 文件內容如下
```
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
BROKER_URL = "redis://127.0.0.1:6379/1"
CELERY_RESULT_BACKEND = "redis://127.0.0.1:6379/2"
```
`config.py`文件內容如下
```
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
from celery import Celery
from app.tasks import config
# 定義 celery 對象
celery_app = Celery("tasks_app")
# 引入配置信息
celery_app.config_from_object(config)
# 自動搜尋異步任務
celery_app.autodiscover_tasks(["app.tasks.compute"])
```
在 `app/tasks/compute` 目錄下新建 `tasks.py` 文件,內容如下
```
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
from app.tasks import celery_app
import time
@celery_app.task
def mycomputer(num):
time.sleep(5)
return num ** 9
```
引入了時間模塊,睡眠一段時間,主要表示這是一個很耗時的操作
在 `app/api_1_0/controller/index.py` 文件下添加方法來調用耗時任務
```
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
from app.api_1_0 import bp
from app.tasks.compute.tasks import mycomputer
@bp.route('/jisuan')
def jisuan():
mycomputer.delay(9)
return 'ok \n'
```
## 開啟 Celery 的后臺任務
```
(.venv) root@airvip:~/python_app/flask-demo# celery -A app.tasks worker -l info
/root/python_app/flask-demo/.venv/lib/python3.6/site-packages/celery/platforms.py:797: RuntimeWarning: You're running the worker with superuser privileges: this is
absolutely not recommended!
Please specify a different user using the --uid option.
User information: uid=0 euid=0 gid=0 egid=0
uid=uid, euid=euid, gid=gid, egid=egid,
-------------- celery@airvip v5.0.5 (singularity)
--- ***** -----
-- ******* ---- Linux-4.15.0-99-generic-x86_64-with-Ubuntu-18.04-bionic 2021-01-06 09:31:34
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app: tasks_app:0x7fbf0d06c278
- ** ---------- .> transport: redis://127.0.0.1:6379/1
- ** ---------- .> results: redis://127.0.0.1:6379/2
- *** --- * --- .> concurrency: 1 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
[tasks]
. app.tasks.compute.tasks.mycomputer
```
可以看到,任務正常啟動
## 測試
```
root@airvip:~# curl 127.0.0.1:5000/api/v1.0/jisuan
ok
```
我們可以在我們 redis 第 2 號庫中查看結果
