谈谈python里面关于任务队列

  • 为什么要做任务队列

要回答这个问题我们首先看看在流水线上的案列,如果人的速度很慢,机器的速度比人的速度快很多,就会造成,机器生产的东西没有及时处理,越积越多,造成阻塞,影响生产。

  • 任务队列的意义:

打个比方如果出现人的速度跟不上机器速度怎么办,这个时候我们就需要第三方,监管人员(任务队列)把机器生产的东西,放在一个地方,(队列),然后分配给每个用户,有条不理的执行。

python 里面的celery 模块是一个简单,灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具。它是一个专注于实时处理的任务队列,同时也支持任务调度。

  • 关于安装celery
pip  install Celery

关于celery 的概念介绍

消息队列

消息队列的输入是工作的一个单元,称为任务,独立的职程(Worker)进程持续监视队列中是否有需要处理的新任务。

Celery 用消息通信,通常使用中间人(Broker)在客户端和职程间斡旋。这个过程从客户端向队列添加消息开始,之后中间人把消息派送给职程,职程对消息进行处理。如下图所示:

 

Celery 系统可包含多个职程和中间人,以此获得高可用性和横向扩展能力。

Celery****的架构

Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。

消息中间件

Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成,包括,RabbitMQ,Redis,MongoDB等,这里我先去了解RabbitMQ,Redis

任务执行单元

Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中

任务结果存储

Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括Redis,MongoDB,Django ORM,AMQP等,这里我先不去看它是如何存储的,就先选用Redis来存储任务执行结果。

实战

环境

  • kaillinux 主机两台(192.168.29.234,192.168.29.198)
  • redis (192.168.29.234 )
  • flower (192.168.29.234)
  • 任务脚本(两台都必须部署)

任务脚本

  • tasks.py (计算加减乘除)
import os
import sys
import datetime
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from celery import Celery
from celery import chain, group, chord, Task
import celeryconfig
app = Celery()
app.config_from_object(celeryconfig)
__all__ = ['add', 'reduce','sum_all', 'other']
####################################
# tas #
####################################
@app.task
def add(x, y):
return x + y
@app.task
def reduce(x, y):
return x - y
@app.task
def sum(values):
return sum([int(value) for value in values])
@app.task
def other(x, y):
return x * y
  • celeryconfig.py
!/usr/bin/python
#coding:utf-8
from kombu import Queue
CELERY_TIMEZONE = 'Asia/Shanghai'
####################################
# 一般配置 #
####################################
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT=['json']
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_ENABLE_UTC = True
# List of modules to import when celery starts.
CELERY_IMPORTS = ('tasks', )
CELERYD_MAX_TASKS_PER_CHILD = 40 # 每个worker执行了多少任务就会死掉
BROKER_POOL_LIMIT = 10 #默认celery与broker连接池连接数
CELERY_DEFAULT_QUEUE='default'
CELERY_DEFAULT_ROUTING_KEY='task.default'
CELERY_RESULT_BACKEND='redis://192.168.29.234:6379/0'
BROKER_URL='redis://192.168.29.234:6379/0'
#默认队列
CELERY_DEFAULT_QUEUE = 'celery'
CELERY_DEFAULT_ROUTING_KEY = 'celery'
CELERYD_LOG_FILE="./logs/celery.log"
CELERY_QUEUEs = (
Queue("queue_add", routing_key='queue_add'),
Queue('queue_reduce', routing_key='queue_sum'),
Queue('celery', routing_key='celery'),
)
CELERY_ROUTES = {
'task.add':{'queue':'queue_add', 'routing_key':'queue_add'},
'task.reduce':{'queue':'queue_reduce', 'routing_key':'queue_sum'},
}

关于flower 是监控任务信息的web 图表,默认的配置没有做验证,而且当主机重启时,数据会丢失,所以我们要自定义一个flower 文件

flower github

在234 上flower.py 的脚本

#!/usr/bin/env python
#coding:utf-8
broker_api = 'redis://127.0.0.1:6379/0'
logging = 'DEBUG'
address = '0.0.0.0'
port = 5555
#外部访问密码
#basic_auth=['root:ybl8651073']
persistent=True #持久化celery tasks(如果为false的话,重启flower之后,监控的task就消失了)
db="/root/flower_db"

运行

  • 在198上启动
celery worker -A  tasks --loglevel=info --queues=celery,queue_add --hostname=celery_worker198
  • 在234 上启动
1.  redis服务
2. celery worker -A tasks --loglevel=info --queues=celery,queue_reduce --hostname=celery_worker234
3. celery flower worker -A tasks --config==/root/flower.py

服务验证

  • 在任一台有celeryservice项目代码的服务器上,运行add、reduce、-
  • sum、other任务(测试可简单使用add.delay(1,2)等)
  • add只会在198上运行,
  • sum任务,可能会在198或234服务器的worker节点运行
  • reduce任务,只会在234上运行。
  • other任务可能会在198或者234上运行。

打开监控web 192.168.29.234:5555

  • 随机运行几个任务

  • 分析

  • 也可以通过 curl提交任务

curl -X POST -d '{"args":[1,2]}' http://192.168.29.234:5555/api/task/async-apply/tasks.add

最新文章

  1. Java面试宝典系列之基础排序算法
  2. PRINCE2项目管理七大流程之指导流程
  3. ANSI C与GNU C
  4. CSS3 Transform——transform-origin
  5. HTTP 错误 500(Internal Server Error)
  6. php的分表分库类
  7. iOS进阶——App生命周期
  8. 跨控制器操作-thinkphp
  9. leiningen安装记录
  10. An Data-Scientist Prepares 《数据科学家的自我修养》
  11. 《C/C++专项练习》 — (3)
  12. C++ #if #endif #define #ifdef #ifndef #if defined #if !defined详解 (转)
  13. python8--文件操作 with。。。open语法
  14. api-ms-win-crt-process-l1-1-0.dll 丢失的处理,遇到问题和完美解决
  15. 第4次作业 -- 基于Jenkins的持续集成
  16. 再谈Retina下1px的解决方案
  17. 【汤鸿鑫 3D太极】5年目标规划(基本功、套路、实战搏击)
  18. Java的家庭记账本程序(B)
  19. C++程序设计方法3:派生类对象的构造和析构过程
  20. HDU 1002 - A + B Problem II - [高精度]

热门文章

  1. 洛谷 P2412 查单词
  2. MX2怎样利用Fiddler进行网络数据抓包
  3. 项目PMO工作
  4. IOS算法(二)之选择排序
  5. Android5.1开机LOGO与开机动画【转】
  6. iOS10 推送通知详解(UserNotifications)
  7. Java:笔记-1
  8. 排序系列 之 冒泡排序及其改进算法 —— Java实现
  9. 利用阿里云加速Docker For Windows
  10. putty和xshell使用和免密登录