詳情請見:flask后台作業--rq方案
為什么使用任務隊列?
目的是應用程序中運行時間長或者復雜的異步任務進程優化。防止阻塞對客戶端的響應,公認的做法是將耗時長的任務移交到worker進程(進程池)
什么是任務隊列?
任務隊列為后台作業提供了一個便捷的解決方案。 Worker進程獨立於應用程序運行,甚至可以位於不同的系統上。 應用程序和worker之間的通信是通過消息隊列完成的。 應用程序提交作業,然后通過與隊列交互來監視其進度。 下圖展示了一個典型的實現:
Python中最流行的任務隊列是Celery。 這是一個相當復雜的軟件包,它有很多選項並支持多個消息隊列。 另一個流行的Python任務隊列是Redis Queue(RQ),它犧牲了一些靈活性,比如只支持Redis消息隊列,但作為交換,它的建立要比Celery簡單得多。
Celery和RQ都非常適合在Flask應用程序中支持后台任務,所以我傾向於選擇更簡單的RQ。 不過,用Celery實現相同的功能其實也不難。 如果你對Celery更感興趣,可以閱讀作者的博客中的Using Celery with Flask文章。
使用RQ
RQ是一個標准python第三方軟件包
(venv) $ pip install rq
(venv) $ pip freeze > requirements.txt
此處生成requirements.txt包含了所有安裝過的包的信息(方便在其他環境部署),如:
pip3 install -r requirements.txt
使用消息隊列RQ需要運行Redis服務器,因為我是win10為環境,這里有個坑就是,作者教程似乎是linux系統,因為按照他的教程會出現使用fork的地方,windows平台就會報錯。為了減少折騰,我這里使用wsl,另外不知道是我環境配置問題還是什么問題,有兩個坑需要注意
- 在wsl使用上述命令會導致報錯,但是一旦使用virtualenv創建的虛擬環境進行相同命令就一切正常了
#安裝
sudo pip3 install python3-virtualenv
#創建名為venv的虛擬環境
virtualenv venv
#使用
source venv/bin/activate
- 另外建議把pip換成國內源或者使用
-i 某國內源
,否則有些包下載會因為超時而報錯
#全局操作,pip,pip3通用
mkdir ~/.pip
vim ~/.pip/pip.conf
# 然后將下面這兩行復制進去就好了
[global]
index-url = https://mirrors.aliyun.com/pypi/simple
#國內其他源參考
清華:https://pypi.tuna.tsinghua.edu.cn/simple
中國科技大學 https://pypi.mirrors.ustc.edu.cn/simple/
華中理工大學:http://pypi.hustunique.com/
山東理工大學:http://pypi.sdutlinux.org/
豆瓣:http://pypi.douban.com/simple/
#臨時換源
sudo pip3 install 某個因為timeout報錯的包 -i 鏡像源url
RQ操作
- 啟動redis-server:
sudo service redis-server start
- 創建任務:在app/tasks.py中創建函數,包含一些業務邏輯操作
- 運行RQ Worker:使用
rq worker sometasks
啟動一個worker進程 - 執行任務:
>>> from redis import Redis
>>> import rq
>>> queue = rq.Queue('microblog-tasks', connection=Redis.from_url('redis://'))
>>> job = queue.enqueue('app.tasks.example', 23) # 之前創建的函數,函數參數
>>> job.get_id()
'c651de7f-21a8-4068-afd5-8b982a6f6d32'
參考:
- pip換源:https://www.linuxidc.com/Linux/2019-04/158178.htm
- virtualenv創建虛擬環境 https://www.jianshu.com/p/e7dcdcdeaa73