【flask-进阶】Celery架构和结构分析图

Celery的架构图
【flask-进阶】Celery架构和结构分析图_第1张图片
celery结构分析图
【flask-进阶】Celery架构和结构分析图_第2张图片
项目开发中经常碰到需要使用异步任务的场景,比如一个WEB请求中有运行时间很长的业务运算,如果不采用异步任务,会阻塞当前的web请求,影响用户体验。

celery是python的一个分布式任务调度模块,由消息中间件broker、任务执行体worker、任务执行结果backend三部分组成。

celery通过消息中间件broker实现消息服务,通常broker使用rabbitMQ,redis等,搭建异步任务系统时需要部署相关的消息服务,比如选择用redis,就需要部署redis-server。

任务执行体worker可以分布式的部署到多个节点,比如多台机器或多个docker中。

任务执行结果backend用于保存任务执行结果,通常使用redis、MongoDB等,仍然需要部署相关的服务。

借助docker我们可以将celery与消息服务集成在一起,提供完整的异步任务执行体。

flower(花)是python的一个专门用于监控celery的模块,比如可以在web页面实时显示celery worker的状态、任务的状态等,最重要的,flower还提供了REST API用于方便第三方应用直接触发任务执行、获取任务执行结果等,这也极大地扩展了celery的应用范围,比如一个Java应用也可以通过flower的REST接口使用celery的异步任务系统。

以下介绍一个实例,我们将celery+flower的组合封装成一个docker,然后通过REST接口触发异步任务执行,并查看任务执行结果。
首先看dockerfile:

FROM ubuntu:14.04
 
USER root
 
RUN apt-get update \
  && apt-get install -y --force-yes python python-pip supervisor redis-server \
  && apt-get clean \
  && pip install --upgrade pip && rm -rf /usr/bin/pip && ln -s /usr/local/bin/pip /usr/bin/pip \
  && pip --no-cache-dir install celery==4.0.2 redis==2.10.5 flower==0.9.2 requests==2.18.1 \
 
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
 
EXPOSE 5555
CMD ["/usr/bin/supervisord"]

我们在ubuntu 14.04基础镜像上安装了python、pip、redis-server,以及celery、flower等python module,因为在docker内要启动多个进程,所以安装supervisor通过supervisord.conf配置多进程启动。

supervisord.conf配置文件如下:

[supervisord]
nodaemon=true
logfile=/app/log/supervisord.log
 
[program:redis-server]
command=/usr/bin/redis-server
stdout_logfile=/app/log/redis.log
stderr_logfile=/app/log/redis.log
autostart=true
 
[program:celery]
command=bash -c "sleep 25 && celery worker -A task -Q common --loglevel=info"
stdout_logfile=/app/log/celery.log
stderr_logfile=/app/log/celery.log
autostart=true
 
[program:flower]
command=bash -c "sleep 50 && celery flower -A task --broker=redis://127.0.0.1:6379/6 --port=5555"
stdout_logfile=/app/log/flower.log
stderr_logfile=/app/log/flower.log
autostart=true

以上配置redis-server最先启动,等待25秒启动celery worker,等待50秒启动celery flower。celery注册了task下的任务列表,接下来我们看看task相关的代码。

首先定义一个celery.py文件,启动celery、加载异步task模块以及config配置

# -*- coding:utf-8 -*-
 
from __future__ import absolute_import
from celery import Celery
 
app = Celery('task', include=['task.tasks'])
app.config_from_object('task.config')
 
if __name__ == '__main__':
     app.start()

config.py文件定义了celery的消息中间件redis数据库6以及异步任务执行结果保存redis数据库5

# -*- coding:utf-8 -*-
 
from __future__ import absolute_import
from kombu import Exchange, Queue
 
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/5'
BROKER_URL = 'redis://127.0.0.1:6379/6'

task.py文件定义具体待执行的异步任务,以add为例

from __future__ import absolute_import
from task.celery import app
import time
 
 
@app.task
def add(x, y):
    time.sleep(60)
    return x + y

将docker build并run运行起来:

docker build -t asyncs:1.1 .
docker run -p 55555:5555 -dt --name=asyncs asyncs:1.1
我们将flower的5555端口映射到了宿主机的55555端口,docker启动正常后,可以登录localhost:55555查看flower的web页面
【flask-进阶】Celery架构和结构分析图_第3张图片
最后我们尝试以curl直接调用flower的REST接口驱动task.py中定义的add任务执行,命令直接返回一个taskId,并显示状态是PENDING,

curl -X POST -d '{"args":[1,2]}'  http://localhost:55555/api/task/async-apply/task.add
{"task-id": "e553be44-b2e5-4ae8-8517-6de98008e849", "state": "PENDING"}

flower的WEB页面显示任务已经启动,
在这里插入图片描述
等任务执行结束,界面将有result结果显示出来。也可以通过之前返回的taskId查询任务进展及结果:

curl http://localhost:55555/api/task/result/e553be44-b2e5-4ae8-8517-6de98008e849
{"task-id": "e553be44-b2e5-4ae8-8517-6de98008e849", "state": "SUCCESS", "result": 3}

你可能感兴趣的:(Flask)