使用Docke配置Rabbitmq及Celery的使用

消息队列选择

这里对之前celery异步任务的使用做个总结,在生产环境使用celery时,最好选择rabbitmq作为消息队列更为稳定,测试时也可以使用redis,简单快捷。

RabbitMQ架构

Rabbitmq架构示意图

基于AMQP协议,使用Channel进行连接和数据传输

  • client客户端
    1. 生产者Publisher:负责产出任务,写入指定的消息队列中;
    2. 消费者Consumer:负责消费任务,从关联的消息队列中获取任务并执行;
  • server服务端(broker)
    Rabbitmq,其内部为可以为不同用户划分不同的Virtual Host,每个Virtual Host内包含交换机和队列两部分。默认只有一个Virtual Host。
    1. 交换机:用于按规则分发任务给指定队列,生产者可方便的只与交换机进行关联;
    2. 队列:用于存放任务,一个rabbitmq中可以有多个消息队列。

使用docker安装rabbitmq

rabbitmq的正产安装比较麻烦,所以这里选择使用docker进行安装。

  • 拉取镜像
sudo docker pull rabbitmq:management

如果速度很慢,可以去阿里云:https://cr.console.aliyun.com/
免费注册并获取镜像加速器,配置方法很简单,官方有说明。

  • 生成容器并运行
sudo docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management
  • RabbitMQ可视化管理
  1. 启动可视化管理界面:sudo rabbitmq-plugins enable rabbitmq_management,使用http://server-ip:15672访问界面
  2. 创建普通用户:sudo rabbitmqctl add_user [username] [password]
  3. 设置用户为管理员:sudo rabbitmqctl set_user_tags [username] administrator
  4. 用户添加管理权限:sudo rabbitmqctl set_permissions -p /[username] '.''.''.*'
  • Rabbitmq相关命令
  1. 查看用户:sudo rabbitmqctl list_users
  2. 查看队列:sudo rabbitmqctl list_queues
  3. 查看交换机:sudo rabbitmqctl list_exchanges
  4. 查看连接:sudo rabbitmqctl list_connections
  5. 查看消费者:sudo rabbitmqctl list_consumers
  • 管理界面测试
    在宿主机上访问:127.0.0.1:15672管理界面,默认可使用账号密码是guest,能访问到证明安装成功


    image.png

Celery工作流

Celery工作流
  • Task
    由我们自己编写的需异步执行的任务函数,也可以是定时任务
  • Broker
    中间人,接收生产者发来的消息即Task,将任务存入队列。任务的消费者是Worker。Celery本身不提供队列服务,推荐用Redis或RabbitMQ实现队列服务,但是Redis有丢任务的风险。
  • Worker
    消费者,执行任务的单元,它实时监控消息队列,如果有任务就获取任务并执行它。
  • Beat
    定时任务调度器,根据配置定时将任务发送给Broler。
  • Backend
    用于存储任务的执行结果。

创建Celery实例

在tasks.py文件中创建Celery实例,broker为中间人,用来存放任务,可使用rabbitmqredis;backend用于储存任务执行的结果,这里也可不指定。

from celery import Celery
imort time
# 实例化Celery对象,指定rabbitmq
app = Celery("task1", broker="amqp://",backend="rpc://")
@app.task
def add(x, y):
    print("计算2个值的和: %s %s" % (x, y))
    return x+y

@app.task
def multi(x,y):
    #模拟阻塞任务
    time.sleep(3)
    print("发送短信成功")
    return x * y
  • Django中的处理
    在Django中使用的话需要使用Django的配置环境,在创建celery实例之前,先在其上方使用以下配置为celery程序设置默认的Django设置模块,后面是你的设置文件。
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dailyfresh.settings')

启动celery worker监听

若不需要创建日志文件时,按如下启动worker监听:
切换到task1所在目录,使用命令开启监听:task1为创建实例时指定的名字

celery -A task1 worker --loglevel=info 

配置日志文件

若需要独立的日志文件记录Celery运行状态,需要使用celery自带的日志记录器。

  • 设置celery日志记录器
from celery.utils.log import get_task_logger
logger = get_task_logger('mycelery')

logger.info('Refresh task start and refresh success')

并在启动celery worker的时候指定日志存放位置,不指定的情况将会默认生成在/var/lib/docker/目录。

  • 启动celery worker命令
celery -A task worker --loglevel=info -f [存放日志的绝对路径]

调用任务,异步执行

在其他地方导入celery实例,调用任务,该任务将以非阻塞的方式异步执行。

from tasks import add, multi
print('开始')
add.delay(1,2)
multi.delay(4,4)
print('结束')
  • 运行情况
    你会发现,在主程序窗口,程序没有任何阻塞的瞬间运行完成,在任务函数中的time.sleep(3)并没有使主程序阻塞。这里的代码只是将任务发布到了消息中间件中,是不能直接获取执行结果的,执行结果保存到了你指定的backend中。
    主程序运行情况

    再看下后台监听程序:
    worker监听

你可以发现,celery自动在后台完成了任务,原本会阻塞主程序的任务在后台以异步的方式完成了。

  • 获取执行结果
    当然,若你想在当前位置获取执行结果也是可以的,可以使用get()方法获取,不过这会阻塞主程序,没有意义。也可使用ready()非阻塞方法判断任务是否执行完成。

定时任务

在celery4版本中,定时任务可以像普通任务一样单独定义,这里需要用到@app.on_after_configure.connect装饰器,详细情况有兴趣可以单独查找,网上资料很多,个人使用不多,因为在某些场景,celery的定时任务不能动态添加。对于定时任务更倾向于使用APScheduler,在框架中使用更方便简单。

使用场景

你能想到在某些特殊场景下,这种任务队列的机制是很有用的。比如邮件、短信发送等任务,需要调用第三方进行,而这些任务的耗时情况使我们不能控制的,为了不阻塞主程序,可以直接使用Celery+Rabbitmq或者Redis,将这些任务直接扔到消息队列中,让他们以异步的方式自动调用执行。

最后

这里这是对celery的最基本实用做了介绍,需要了解更多功能可以查看更多其他资料,比如任务重试、异常处理、返回结果获取等。需要注意的是,如果修改了任务内容,需要重启worker监听和IDE再执行才能生效。

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

推荐阅读更多精彩内容