分布式任务队列与任务调度系统Celery入门

    Celery是基于Python的开源分布式任务队列与任务调度系统。

    1.什么是任务队列呢?

    任务队列是一个将任务分布到多线程或多台机器上的一种机制。一个任务队列的输入(一个任务)是一个工作单元。专用的工作者进程将会持续监控任务队列并执行其中的任务。

    2.Celery的模块架构


    任务代理/中间人(broker)

    celery扮演生产者和消费者的角色,broker就是生产者和消费者存放/拿去产品的地方(任务队列)。任务代理方负责接受任务生产者发送过来的任务消息,存进队列之后再进行调度,分发给任务消费者。因为任务处理是基于消息的,所以我们一般选择RabbitMQ、Redis等消息队列或者数据库作为Celery的message broker。

    任务生产者(task producer)

    任务生产者(task producer)负责生产计算任务,交由任务队列broker去处理。

    任务调度器(celery beat)

    celery beat是一个任务调度器,它以独立进程的形式存在。celery beat 进程会读取配置文件的内容,周期性地将任务的请求发送给任务队列。celery beat 是celery系统自带的任务生产者。系统管理员可以选择关闭或开启celery beat。同时在一个celery系统中,只能存在一个celery beat调度器。

    任务消费者(celery worker)

    celery worker就是执行任务的一方,它负责接收任务代理发送过来的任务处理请求,完成这些任务,并且返回任务处理的结果。celery worker对应的就是操作系统中的一个进程。celery支持分布式部署和横向拓展,我们可以在多个节点增加celery worker的数量来增加系统的高可用性。在分布式系统中,我们可以在不同节点分配不同任务的celery worker来达到模块化的目的。

    结果保存(Result Stores / backend)

    顾名思义就是结果存放的地方,celery支持任务处理完后将状态信息和结果的保存,以供查询。celery内置支持rpc,django orm,redis,RabbitMQ等方式来保存任务处理后的状态信息。

3.快速开始

    以下实例均在Python3.5.3下编译通过。

    首先安装celery模块:python3 -m pip install celery

    安装redis服务器:apt-get install redis-server

    安装python3的redis模块:python3 -m pip install redis

    安装request库:python3 -m pip install requests

    安装BeautifulSoup:python3 -m pip install bs4

    然后,我们先看一个不使用celery的脚本。

#encoding:utf-8
import requests
import time

def func(urls):
    start = time.time()
    for url in urls:
        resp = requests.get(url)
        print(resp.status_code)
    end=time.time()
    return str(end-start)

if __name__ == "__main__":

    t=func(["http://www.zhainanbang.net", "http://jd.com", "https://taobao.com", "http://baidu.com", "http://www.secapi.net","http://blog.csdn.net"])
    print("耗时:"+t)

接下来,我们我们使用celery,修改下原来的脚本。

#encoding:utf-8
from celery import Celery
import requests
import time

app=Celery('usecelery',broker='redis://localhost:6379/0',backend='redis://localhost:6379/0')

@app.task
def fetch_url(url):
    resp=requests.get(url)
    print(resp.status_code)


def func(urls):
    start = time.time()
    for url in urls:
        fetch_url.delay(url)


if __name__ == "__main__":

    func(["http://www.zhainanbang.net", "http://jd.com", "https://taobao.com", "http://baidu.com", "http://www.secapi.net","http://blog.csdn.net"])

我们需要开3个终端:

    第一个终端,运行:redis-server

    第二个终端,运行: celery worker -A usecelery  -l info -c 10

    第三个终端,运行:python3 usecelery.py

    我们可以看到输出信息,耗时为0.85秒

 上面的这个例子我们只是些了一个celery任务,但是我们可能会有多个任务。因此我们将新建一个celery_config.py

用来配置多个任务。

from celery import Celery

app=Celery('celery_config',broker='redis://localhost:6379/0',backend='redis://localhost:6379/0',include=['usecelery','addcelery'])
我们修改usecelery.py的代码为:

#encoding:utf-8
from celery_config import app
import requests
import time


@app.task
def fetch_url(url):
    resp=requests.get(url)
    print(resp.status_code)


def func(urls):
    start = time.time()
    for url in urls:
        fetch_url.delay(url)
创建另外一个任务文件adcelery.py,代码如下:

from celery_config import app

@app.taskdef add(a,b):
    return a+b
然后我们新建一个task.py文件,用来执行两个任务。代码如下:

from addcelery import add
from usecelery import func

if __name__=='__main__':
    func(["http://www.zhainanbang.net", "http://jd.com", "https://taobao.com", "http://baidu.com", "http://www.secapi.net","http://blog.csdn.net"])

    for i in range(1,10):
        add.delay(i,i%3)

  在一个终端中运行:celery worker -A celery_config  -l info -c 10

    在另外一个终端中执行Python3 task.py

    执行效果如下:

那么如何分布式部署呢?我会在下一篇文章中做介绍。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MXi4oyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值