java中有类似celery,分布式队列神器 Celery,你了解多少?

Brokers

意为中间件/中间人,在这里指的是任务队列, 我们要注意Celery本身不是任务队列,它是管理分布式任务队列的工具,换一句话说,用Celery可以快速进行任务队列的使用与管理, Celery可以方便的和第三方提供的任务队列集成,例如RabbitMQ, Redis等。

Worker

任务执行单元,我们可以理解为工人,Worker是Celery提供的任务执行的单元,简单来说,它就是Celery的工人,类似于消费者,它shi'shi监控着任务队列,当有新的任务入队时,它会从任务队列中取出任务并执行。

backend/Task result store

任务结构存储,顾名思义,它就是用来存储Worker执行的任务的结果的地方,Celery支持以不同方式存储任务的结果,有redis,Memcached等。

简单来说,当用户、或者我们的应用中的触发器将任务入Brokers队列之后,Celery的Worker就会取出任务并执行,然后将结构保存到Task result store中。

使用Celery

简单实现

Celery及消息队列(redis/RabbitMQ)的安装过程在这里就不再赘述了,出于方便,我们这里使用redis,点击这里查看官网给出的更多的Brokers和backend支持。

首先,我们新建一个tasks.py文件。

importtime

fromcelery importCelery

brokers = 'redis://127.0.0.1:6379/0'backend = 'redis://127.0.0.1:6379/1'

app = Celery('tasks', broker=brokers, backend=backend)

@app.taskdefadd(x, y):

time.sleep(2)

returnx + y

上述代码,我们导入了celery库,新建了一个celery实例,传入了broker和backend,然后创建了任务函数add,我们用time.sleep(2)来模拟耗时操作。

接下来我们要启动Celery服务,在当前命令行终端运行:

celery -A tasks worker  --loglevel=info

注意:如果在Windows中要运行如下命令:

celery -A celery_app worker --loglevel=info -P eventlet

不然会报错。。。。。。

我们会看到下面的输出结果:

D:\use_Celery>celery -A tasks worker --loglevel=info -P eventlet

-------------- celery@DESKTOP-8E96VUV v4.4.2(cliffs)

--- ***** -----

-- ******* ---- Windows-10-10.0.18362-SP0 2020-03-18 15:49:22- *** --- * ---

- ** ---------- [config]

- ** ---------- .> app: tasks:0x3ed95f0- ** ---------- .> transport: redis://127.0.0.1:6379/0- ** ---------- .> results: redis://127.0.0.1:6379/1- *** --- * --- .> concurrency: 8(eventlet)

-- ******* ---- .> task events: OFF (enable -E to monitor tasks inthis worker)

--- ***** -----

-------------- [queues]

.> celery exchange=celery(direct) key=celery

[tasks]

. tasks.add

[2020-03-18 15:49:22,264: INFO/MainProcess] Connected to redis://127.0.0.1:6379/0[2020-03-18 15:49:22,294: INFO/MainProcess] mingle: searching forneighbors

[2020-03-18 15:49:23,338: INFO/MainProcess] mingle: allalone

[2020-03-18 15:49:23,364: INFO/MainProcess] celery@DESKTOP-8E96VUV ready.

[2020-03-18 15:49:23,371: INFO/MainProcess] pidbox: Connected to redis://127.0.0.1:6379/0.

这些输出包括指定的启动Celer应用的一些信息,还有注册的任务等等。

此时worker已经处于待命状态,而 broker中还没有任务 ,我们需要触发任务进入broker中,worker才能去取出任务执行。

我们新建一个add_task.py文件:

fromtasks importadd

result = add.delay(5, 6) #使用celery提供的接口delay进行调用任务函数

while notresult.ready():

passprint("完成:", result.get())

我们可以看到命令窗口的输出的celery执行的日志 :

[2020-03-18 15:53:15,967: INFO/MainProcess] Received task: tasks.add[8da270cb-7f07-4202-ad6a-51cc7f559107]

[2020-03-18 15:53:17,981: INFO/MainProcess] Task tasks.add[8da270cb-7f07-4202-ad6a-51cc7f559107] succeeded in2.015999999974156s: 11

当然我们在backend的redis中也可以看到执行任务的相关信息。

至此,一个简单的 celery 应用就完成啦。

56186e417bedf253f3c8059c83d428d3.png

周期/定时任务

Celery 也可以实现定时或者周期性任务,实现也很简单,只需要配置好周期任务,然后再启动要启动一个 beat 服务即可。

新建Celery配置文件celery_conf.py:

fromdatetime importtimedelta

fromcelery.schedules importcrontab

CELERYBEAT_SCHEDULE = {

'add': {

'task': 'tasks.add',

'schedule': timedelta(seconds=3),

'args': (16, 16)

}

}

然后在 tasks.py 中通过app.config_from_object('celery_config')读取Celery配置:

# tasks.py

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

app.config_from_object('celery_config')

然后重新运行 worker,接着再运行 beat:

celery -A tasks beat

我们可以看到以下信息:

D:\use_Celery>celery -A tasks beat

celery beat v4.4.2(cliffs) isstarting.

__ - ... __ - _

LocalTime -> 2020-03-18 17:07:54Configuration ->

. broker -> redis://127.0.0.1:6379/0. loader -> celery.loaders.app.AppLoader

. scheduler -> celery.beat.PersistentScheduler

. db -> celerybeat-schedule

. logfile -> [stderr]@%WARNING

. maxinterval -> 5.00minutes (300s)

然后我们就可以看到启动worker的命令行在周期性的执行任务:

[2020-03-18 17:07:57,998: INFO/MainProcess] Received task: tasks.add[f5dab8ac-0809-415f-84e7-cba488ea2495]

[2020-03-18 17:07:59,995: INFO/MainProcess] Task tasks.add[f5dab8ac-0809-415f-84e7-cba488ea2495] succeeded in2.0s: 32[2020-03-18 17:08:00,933: INFO/MainProcess] Received task: tasks.add[b49a4c92-e007-46ef-9b5d-f93f451a6c1b]

[2020-03-18 17:08:02,946: INFO/MainProcess] Task tasks.add[b49a4c92-e007-46ef-9b5d-f93f451a6c1b] succeeded in2.0160000000032596s: 32[2020-03-18 17:08:03,934: INFO/MainProcess] Received task: tasks.add[1bdfe4d8-76c1-44cc-b1fa-dbbe242692ae]

[2020-03-18 17:08:05,940: INFO/MainProcess] Task tasks.add[1bdfe4d8-76c1-44cc-b1fa-dbbe242692ae] succeeded in2.0s: 32

可以看出每3秒就有一个任务被加入队列中去执行。

那定时任务又怎样去实现呢?

也很简单,我们只需要更改一下配置文件即可:

CELERYBEAT_SCHEDULE = {

'add-crontab-func': {

'task': 'tasks.add',

'schedule': crontab(hour=8, minute=50, day_of_week=4),

'args': (30, 20),

},

}

CELERY_TIMEZONE = 'Asia/Shanghai'#配置时区信息

其中crontab(hour=8, minute=50, day_of_week=4)代表的是每周四的8点50执行一次,只要我们的Celery服务一直开着,定时任务就会按时执行;在这里我也在配置里加入了时区信息。

我在这里是8点45启动的Celery服务、运行的beat,从下面的输出可以看出,50的时候我们的定时任务就执行了。

[2020-03-19 08:45:19,934: INFO/MainProcess] celery@DESKTOP-8E96VUV ready.

[2020-03-19 08:50:00,086: INFO/MainProcess] Received task: tasks.add[45aa794d-a4ef-40e0-9480-80c7004318d5]

[2020-03-19 08:50:02,091: INFO/MainProcess] Task tasks.add[45aa794d-a4ef-40e0-9480-80c7004318d5] succeeded in2.0s: 50

由此我们可以看出,利用 Celery 进行分布式队列管理将会大大的提高我们的开发效率,我这里也仅仅是关于Celery的简单介绍和使用,如果大家感兴趣,可以去官方文档 学习更高级更系统的用法。

最后,感谢女朋友在生活中,工作上的包容、理解与支持 !

ee1efd7c2fb7fddf5008bc80d95fa66a.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值