django_rq 实战笔记

应用场景

我目前开发一个django项目,前段时间接触到一个需求,需要做大量耗时任务的异步处理,之前这个功能是用threading直接做的,众所周知,threading做异步,一旦服务挂掉或者重启,任务会全部丢失,所以需要其他解决办法

为什么用rq

本来,这个需求直指消息队列,所以我打算用RabbitMQ+Celery去做,正准备操起键盘就是干,一通梭,正此时,前端同事凑过来跟我说,朋友,你有没有听过rq?

rq?所谓有啥不会,百度全对,于是我冲进rq官方文档。

RQ(Redis Queue),人如其名,用 redis 做的队列任务

redis ,众所周知, 它的列表可以做队列,rq就是把job放进队列里,然后启worker挨个做完

另外rq极其简单,官方文档短小精悍,容易上手

手把手教你Django_rq

安装

直接 pip install django-rq 

会自动安装依赖库 rq

配置

setting.py

#引入django_rq,使得python manage.py 命令可以使用

INSTALLED_APPS = [

    # other apps

    "django_rq",

]

#配置队列

RQ_QUEUES = {

"default": {

"HOST":"127.0.0.1",

        "PORT":6379,

        "DB":1,

        "URL": os.getenv(

"REDISTOGO_URL", "redis://127.0.0.1:6379/1"

        ),  # If you're on Heroku

    },

    "high": {

"HOST":"127.0.0.1",

        "PORT":6379,

        "DB":1,

        "URL": os.getenv(

"REDISTOGO_URL", "redis://127.0.0.1:6379/1"

        ),  # If you're on Heroku

    },

    "low": {

"HOST":"127.0.0.1",

        "PORT":6379,

        "DB":1,

        "URL": os.getenv(

"REDISTOGO_URL", "redis://127.0.0.1:6379/1"

        ),  # If you're on Heroku

    },

}

#default, high, low 表示队列的优先级,如果同时入队,优先执行high队列的,其次执行default队列的,最后执行low

# 但是如果一大批low队列的job在执行的话,此时high队列开始入队job,不会马上下一个任务就开始执行high队列,而是会继续执行low队列,直至low队列任务执行完毕

# "HOST":"127.0.0.1", "PORT":6379,"DB":1, 是在配置redis数据库

#还有其他参数可以配置,具体可以看看django_rq官方文档,附上源码和文档https://gitee.com/mirrors/django-rq?_from=gitee_search

urls.py

urlpatterns += [

    path(r'admin/django-rq/', include('django_rq.urls')),

]

#把 rq 队列数据详情放入django admin后台管理中,如下图




开始撸代码

import django_rq

salt = uuid.uuid1()

rq_id = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S") + salt

#job_id可以自己制定也能自动生成,但一定注意不能重名,否则重名的任务会覆盖

queue = django_rq.get_queue(

"default", autocommit=True, is_async=True, default_timeout=3600

)

#拿到队列,进入之前setting.py设置的"default"队列,异步设置为True(默认的,可以不设置),default_timeout = 3600(任务超时为3600s,按照队列该任务开始执行开始算起)

queue.enqueue(

"apps.xxx.xxx.xxxx.views.task", args=(task_arg1, task_arg2), result_ttl=31536000, job_id=rq_id

)

#入队,apps.xxx.xxx.xxxx.views是文件名称,task是函数名称,函数必须是独立的函数,否则在类中定义的话无法识别,也可以直接引入就在当前文件的函数,不必加引号

#args=(task_arg1, task_arg2)存放的是task的参数,参数可以为多个,但必须是基础类型,不能是对象,类,

# result_ttl=31536000是指执行完毕之后结果在redis数据库中保留的时间

#还有其他的参数,大家可以自己看看rq文档http://python-rq.org/

#django_rq还支持 @job来自动入队

执行任务

python manage.py rqworker high default low

#在 high default low三个队列各自启动一个worker,注意了,由于django_rq调用linux中fork(),所以只能在linux系统中执行,windos可以尝试win10的子系统

线上环境启动

ubuntu为例

写systemctl 启动配置
sudo vi /etc/systemd/system/rqworker.service

内容

[Unit]

Description=Django-RQ Worker

After=network.target

[Service]

WorkingDirectory=<<path_to_your_project_folder>>

ExecStart=/home/ubuntu/.virtualenv/<<your_virtualenv>>/bin/python \

    <<path_to_your_project_folder>>/manage.py \

    rqworker high default low

[Install]

WantedBy=multi-user.target


执行命令

sudo systemctl enable rqworker

sudo systemctl start rqworker

注意,无论那种方式只是启动了一个work,想要启动多个work  需要多线程执行 python manage.py rqworker high default low

大家可以自己写脚本实现,可以参考这篇文章http://xiaorui.cc/archives/2334,可以使用supervisord 来管理进程

查看队列执行状况

多种办法

1.配置好的django admin中查看,种类齐全,最佳查看方式

2.python manage.py rqstats

python manage.py rqstats --interval=1  #每秒刷新(其实刷新并不及时)

python manage.py rqstats --json  # 输出JSON

python manage.py rqstats --yaml  # 输出YAML

3. 进入redis库中可以看到自己的队列,worker,以及job(作为辅助验证使用)

4.rq 也有命令可以启动 和查看状态,大家可以自己看看

其他

worker其实也可以自己手写启动脚本,很多参数都可以自己配置,如果看到django_rq的源码就会发现django_rq就是简单集成django,功能基本都是调用rq实现,甚至rq都可以自己重构,添加想要的功能,工具在于使用,不必完全遵循。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351