Celery #4 結合Flask和apscheduler使用
更進一步地,我們希望可以用一個web服務呼叫Celery,這樣我們可以改通過web服務檢視任務的執行。
Celery本身可以用beat定時,也提供了一定的狀態監視手段。但我們需要動態更改任務計劃和持久化任務記錄時,自建一套邏輯也許更加方便。
具體方案
思路:
實現一個Flask例項作為web服務,通過apscheduler在web程式中實現定時計劃。
任務執行前後,將相關時間、狀態、異常、結果等寫入mongoDB儲存。
通過web服務檢視celery轉檯、任務、任務執行記錄等。
- 由於不再依賴訊息佇列獲取結果,可以不設定backend。
- 這樣設計的問題是,不能捕捉到celery併發限制後,位於排隊序列裡的任務。記錄的是任務實際開始執行的時間。
現在目錄下有檔案:
tasks.py
admin.py
其內容:
# tasks.py
import time
import functools
from pymongo import MongoClient
from celery import Celery
conn = MongoClient()
log = conn.tasklog.log
app = Celery('tasks', broker='redis://localhost:6379/9')
def task_log(func):
'任務裝飾器。向mongo寫入狀態資訊'
@functools.wraps(func)
def wrapper(*args, **kargs):
task_name = func.__name__
log_id = log.insert({
'name': task_name,
'start_time': int(time.time() * 1000),
'end_time': 0,
'status': 0,
})
try:
result = func(*args, **kargs)
log.update({
'_id': log_id
}, {
'$set': {
'end_time': int(time.time() * 1000),
'status': 1,
'result': str(result)
}
})
return result
except Exception as e:
print(e)
log.update({
'_id': log_id
}, {
'$set': {
'end_time': int(time.time() * 1000),
'status': 2,
'err': str(e)
}
})
return wrapper
@app.task
@task_log
def add(x, y):
print('{} add {} equals {}'.format(x, y, x+y))
return x + y
# admin.py
from celery.local import PromiseProxy
from flask import Flask, request
from apscheduler.schedulers.background import BackgroundScheduler
from pymongo import MongoClient
from utils.mkresp import mkresp
import tasks
conn = MongoClient()
log = conn.tasklog.log
# 讀取所有任務
TASKS = {}
for attrname in dir(tasks):
attr = getattr(tasks, attrname)
if type(attr) == PromiseProxy:
TASKS[attrname] = attr
# 定時任務計劃
sched = BackgroundScheduler()
#每分鐘執行一個add任務
sched.add_job(tasks.add.delay, 'cron', minute='*', args=(5,5))
sched.start()
# Flask app
app = Flask(__name__)
@app.route('/')
def r_index():
return 'admin'
@app.route('/tasks')
def r_tasks():
return mkresp(msg=list(TASKS.keys()))
@app.route('/tasklogs')
def r_tasklogs():
docs = list(log.find())
return mkresp(msg=docs)
@app.route('/taskrun/<string:taskname>')
def r_task_run(taskname):
params = request.values.get('params')
params = json.loads(params)
print(params)
task = TASKS.get(taskname)
if not task:
return mkresp(code=500, msg='不存在指定任務')
task.delay(*params)
return mkresp()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000)
使用celery -A tasks worker --loglevel=info -P gevent
啟動celery,再執行admin.py。
現在,訪問http://localhost:9000/tasks
即可看到所有任務。
訪問http://localhost:9000/tasklogs
即可看到所有任務執行記錄。
訪問http://localhost:9000/taskrun/add?params=[1,2]
即可立即執行add任務,引數1,2。
相關文章
- flask非同步資料交換celery的使用Flask非同步
- 在 Flask 專案中使用 Celery(with 工廠模式 or not)Flask模式
- Celery非同步排程框架(二)與Django結合使用非同步框架Django
- APScheduler的基本使用
- APScheduler的使用詳解
- celery 與 flask 實現非同步任務排程Flask非同步
- celery筆記一之celery介紹、啟動和執行結果跟蹤筆記
- `GitHub page` 和 `gitbook` 結合使用Github
- 結合使用 Hadoop 和 CouchbaseHadoop
- LlamaIndex RAG 和ReAct結合使用AIIndexReact
- Unity結合Flask實現排行榜功能UnityFlask
- Celery 進階使用
- django中使用celeryDjango
- 關於CAEmitterLayer和CAEmitterCell結合使用MIT
- Python APScheduler介紹及使用Python
- 基於 flask 結合 Redis 的簡單聊天室FlaskRedis
- 在django中使用celeryDjango
- jenkins的安裝和配置(flask結合jenkins半自動化部署流程)JenkinsFlask
- react-hook-form結合antd4使用學習ReactHookORM
- Django專案中使用CeleryDjango
- sed命令和find命令的結合的使用
- celery4+django2定時任務Django
- 使用uwsgi和Nginx部署flask應用NginxFlask
- flask:flask模板——使用Jinja2Flask
- 結合S/4HANA和雲遷移:企業如何受益
- Go和JavaScript結合使用:抓取網頁中的影像連結GoJavaScript網頁
- celery 在django專案中使用Django
- 《Flask 入門教程》第 4 章:使用靜態檔案Flask
- APScheduler 學習心得
- python APScheduler模組Python
- 使用flask開發RESTful架構的api伺服器端(4)–flask運算元據庫FlaskREST架構API伺服器
- go-kit結合gRpc的使用和學習GoRPC
- 使用flask開發RESTful架構的api伺服器端(2)–flask的安裝和使用FlaskREST架構API伺服器
- [譯] 使用 Stripe, Vue.js 和 Flask 接受付款Vue.jsFlask
- 使用 Flask 和 rauth 進行 Github Oauth 登陸FlaskGithubOAuth
- 在django中使用celery(而不是djcelery)Django
- Nginx和Perl的結合Nginx
- Nginx和php的結合NginxPHP