详情请见: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