概述
?? celery是一個python實現的分布式任務執行框架,本文為學習筆記:
- python 3.8.6
- celery 5.1.2
- 操作系統 win10
- redis 3.0.504
安裝
- pip install celery
- pip install flower (任務監控平臺)
- pip install eventlet (win10 環境需要)
image.png
參考官網上面的例子,將celery 當成一個獨立工程來維護,方便將已有的業務按統一規范寫成任務入口函數
目錄結構如下:
image.png
celery.py 文件代碼:
from celery import Celery
app = Celery('proj',
broker='redis://:123456@10.2.13.167:6379/1',
backend='redis://:123456@10.2.13.167:6379/2',
include=['proj.tasks'])
# Optional configuration, see the application user guide.
app.conf.update(
result_expires=3600,
)
if __name__ == '__main__':
app.start()
tasks.py 文件代碼如下:
from .celery import app
@app.task
def add(x, y):
print("call add")
return x + y
@app.task
def mul(x, y):
return x * y
@app.task
def xsum(numbers):
return sum(numbers)
啟動服務
- 啟動 celery celery -A proj worker -l INFO -P eventlet
- 啟動 flower celery -A proj flower --address=127.0.0.1 --port=5566 # web監控頁面打開方式 http://127.0.0.1:5566
直接ctrl+c 退出程序
在liunx上面 支持以 守護進程方式啟動 celery multi start w1 -A proj -l INFO multi 其它參數:重啟是 restart 停止是stop,還支持啟動多個worker 這里是只啟動了一個,具體參數參考官方文檔
集成到flask框架中
?? celery集成到flask框架中不需要安裝任何擴展,網上有其它的方式進行集成,本人采用的是,直接調用 tasks.py 下面的任務函數的方式實現
代碼如下:
from flask import Flask, request
from proj.tasks import app, add, mul
from celery.result import AsyncResult
flask_app = Flask(__name__)
@flask_app.route('/add', methods=["POST"])
def celery_add():
"""
執行add任務
POST http://127.0.0.1:5000/add
Body 為表單 參數為 args1,args2
:return:
"""
try:
args1, args2 = request.form.values()
print(f"獲取到的參數:{args1},{args2}")
except Exception as e:
return str(e)
result = add.delay(int(args1), int(args2))
result_id = result.id
print(f"任務id:{result_id}")
return result_id
@flask_app.route('/get_result', methods=["GET"])
def get_result_id():
"""
根據id獲取任務結果
GET http://127.0.0.1:5000/get_result?id=fd7cb7dc-5b1b-4e07-8199-dd89a0c08a2a
:return:
"""
result_id = request.args.get('id')
async_result = AsyncResult(id=result_id, app=app)
result = ""
if async_result.successful():
result = async_result.get()
print(result)
# result.forget() # 將結果刪除
elif async_result.status == 'PENDING':
print('任務等待被執行')
elif async_result.status == 'RETRY':
print('任務異常后重試')
elif async_result.status == 'STARTED':
print('任務執行中')
elif async_result.failed():
print('任務執行失敗')
return str(result)
if __name__ == "__main__":
flask_app.run("127.0.0.1", port=5000)
啟動flask程序
通過postman進行調用測試:
-
調用add函數,獲取任務id:
image.png -
獲取對應id的結果:
image.png -
打開flower 查看調用過程 如下圖:
image.png