【干货分享】NTI任务管理之django+python篇celery异步任务使用

新浪微博的新鲜事推送如何实现?大规模的服务器如何实现Crontab管理?里面的秘密就在于消息队列。Celery是一个使用Python开发的分布式任务调度模块,是一个简单、灵活、可靠的处理大量消息的分布式系统。在大量异步任务处理和大量定时任务管理的情况下,我们可以优先考虑采用celeryrabbitMq解决这些问题。本文介绍了Celery以及Django中Celery的实现。

为什么要用celery

   Celery是一个使用Python开发的分布式任务调度模块,是一个简单、灵活、可靠的处理大量消息的分布式系统,他是一个专注于实时处理的任务队列,同时也支持任务调度。因此适合实时异步任务、定时任务等调度场景。

    【注:何为任务队列?任务队列是一种在线程或机器间分发任务的机制。消息队列的输入是工作的一个单元,称为任务,独立的职程(Worker)进程持续监视队列中是否有需要处理的新任务。)】。

celery适用于那些场景

     应用场景一:我们知道大型网站的性能非常重要,然而有时不得不做一些相当耗时的操作。 比如SNS网站的“新鲜事儿”系统,我发帖之后,会给所有关注我的人推送一条通知。乍一看没什么难的,发帖之后找出关注我的人, 然后生成相应的消息记录就行了。但问题是,100个人关注我,就要执行100INSERT查询,更要命的是,Web服务器是同步的, 这100条查询执行完成之前,用户是看不到结果的。怎么办呢,这时就轮到消息队列上场了。发帖之后只需给队列发送一条消息, 告诉队列“我发帖子了”,然后把发帖的结果返回给用户。 这时另一个叫做worker的进程会取出这条消息并执行那100INSERT查询。这样,推送通知的操作在后台异步执行, 用户就能立即看到发帖结果。更精彩的是,可以运行多个worker实现分布式,多繁重的任务都不在话下了。将Celery RabbitMQ 结合,将会产出很好的效果,可以实现类似新浪微博大数据量的消息推送。(这里就可以采用RabbitMQ消息队列系统负责存储消息;采用celeryworken进程,同时提供在webapp中创建任务的功能)。
应用场景二:很多做开发和运维的都会涉及一件事:crontab, 也就是在服务器上设定定时任务,按期执行一些任务.但是假如你有上千台的服务器, 你有上千种任务,那么对于这个定时任务的管理恐怕是一件很头疼的事情.哪怕你只是几十个任务分配的不同的机器上怎么样合理的管理和实现以下功能呢:
查看定时任务的执行情况.比如执行是否成功,当前状态,执行花费的时间;一个友好的界面或者命令行下实现添加,删除任务;怎么样简单实现不同的机器设定不同种任务,某些机器执行不同的队列;假如你需要生成一个任务怎么样不阻塞剩下来的过程;怎么样并发的执行任务。RabbitMQ,ZeroMQ这样的消息队列总是出现在我们视线中, 其实意义是很简单: 消息就是一个要传送的数据,celery是一个分布式的任务队列。这个”任务”其实就是一种消息, 任务被生成到队列中,被RabbitMQ等容器接收和存储,在适当的时候又被要执行的机器把这个消息取走。
以上是两种典型的应用场景。通过上面两种场景的分析,在大量异步任务处理和大量定时任务管理的情况下,我们可以优先考虑采用celeryrabbitMq解决这些问题。

celery特点

  • 简单:Celery 易于使用和维护,并且它不需要配置文件

  • 高可用性:倘若连接丢失或失败,进程和客户端会自动重试,并且通过主/主或主/从方式复制来提高可用性

  • 快速:单个 Celery 进程每分钟可处理数以百万计的任务,而保持往返延迟在亚毫秒级

  • 灵活:Celery 几乎所有部分都可以扩展或单独使用。可以自制连接池、序列化、压缩模式、日志、调度器、消费者、生产者、自动扩展、中间人传输或更多。

工作原理

首先需要了解Celery 的通信机制,Celery 用消息通信,通常使用中间人(Broker)在客户端和职程间斡旋。这个过程从客户端向队列添加消息开始,之后中间人把消息派送给职程。Celery官网给出了多个Broker的备选方案:RabbitMQRedisDatabase(不推荐)以及其他的消息中间件,官方默认推荐的是RabbitMQ。   

它的基本工作就是管理分配任务到不同的服务器,并且取得结果。至于说服务器之间是如何进行通信的?这个Celery本身不能解决。所以,RabbitMQ作为一个消息队列管理工具被引入到和Celery集成,负责处理服务器之间的通信任务。

Django中Celery的实现

NTI的整个项目体系里也避免不了使用定时任务或异步任务去处理一些任务,比如定时的邮件提醒,资产监控,用户操作行为记录等等,下面看看我们是如何使用的:

建立消息队列

首先,我们必须拥有一个broker消息队列用于发送和接收消息。我们就使用RabbitMQ作为我们的消息中间人。在Linux上安装的方式如下:

sudo apt-get install rabbitmq-server

命令执行成功后,rabbitmq-server就已经安装好并运行在后台了。另外也可以通过命令rabbitmq-server来启动rabbitmq server以及命令rabbitmqctl stop来停止server

安装django-celery

pip install django-celery

配置settings.py

  首先,在Django工程的settings.py文件中加入如下配置代码:

其中,当djcelery.setup_loader()运行时,Celery便会去查看INSTALLD_APPS下包含的所有app目录中的tasks.py文件,找到标记为task的方法,将它们注册为celery taskBROKER_URLCELERY_RESULT_BACKEND分别指代你的Broker的代理地址以及Backendresult store)数据存储地址。在Django中如果没有设置backend,会使用其默认的后台数据库用来存储数据。注意,此处backend的设置是通过关键字CELERY_RESULT_BACKEND来配置,与一般的.py文件中实现celerybackend设置方式有所不同。

然后,在INSTALLED_APPS中加入djcelery

4. 在要使用该任务队列的app根目录下(比如:myApp),建立tasks.py

tasks.py中我们就可以编码实现我们需要执行的任务逻辑,本例以求和函数为例,在开始处import task,然后在要执行的任务方法开头用上装饰器@task。需要注意的是,与一般的.py中实现celery不同,tasks.py必须建在各app的根目录下,且不能随意命名。

生产任务

在需要执行该任务的View中,通过create_task_add.delay的方式来创建任务,并送入消息队列。比如

这里仅仅是提供一个参考示例,实际应用中大家可以将一些耗时但不影响用户体验的功能封装成异步任务让其单独在去执行。

启动worker的命令

先启动服务器

python manage.py runserver

再启动worker

python manage.py celery worker -c 4 –loglevel=info

到此,我们django+pythoncelery异步任务使用-1就简单讲完了,本篇主要是对celery的一个简介和一个简单示例使用,更多的关于异步任务、定时任务的的使用,使用过程中踩过的坑等内容后续会持续更新,欢迎有兴趣的同学交流指点。

声 明

本安全公告仅用来描述可能存在的安全问题,绿盟科技不为此安全公告提供任何保证或承诺。由于传播、利用此安全公告所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,绿盟科技以及安全公告作者不为此承担任何责任。绿盟科技拥有对此安全公告的修改和解释权。如欲转载或传播此安全公告,必须保证此安全公告的完整性,包括版权声明等全部内容。未经绿盟科技允许,不得任意修改或者增减此安全公告内容,不得以任何方式将其用于商业目的。

关于绿盟科技

北京神州绿盟信息安全科技股份有限公司(简称绿盟科技)成立于2000年4月,总部位于北京。在国内外设有30多个分支机构,为政府、运营商、金融、能源、互联网以及教育、医疗等行业用户,提供具有核心竞争力的安全产品及解决方案,帮助客户实现业务的安全顺畅运行。

基于多年的安全攻防研究,绿盟科技在网络及终端安全、互联网基础安全、合规及安全管理等领域,为客户提供入侵检测/防护、抗拒绝服务攻击、远程安全评估以及Web安全防护等产品以及专业安全服务。

北京神州绿盟信息安全科技股份有限公司于2014年1月29日起在深圳证券交易所创业板上市交易,股票简称:绿盟科技,股票代码:300369。

如果您需要了解更多内容,可以
加入QQ群:570982169
直接询问:010-68438880

Spread the word. Share this post!

Meet The Author

Leave Comment