celery框架使用

场景1:
在网站A业务中有个操作 是 要在网站B中新建一台服务器跑业务。A中执行B中的接口创建服务器 中间需要的时间很长。A如果一直等着B返回结果会超时。B 执行命令 很耗资源,而且不能执行太多的并发。 这这种需求下 我们想到的就是 传说中的 “消息列队“ 来解决这种分布式事务。

场景2:
你可能想对100台服务器执行一条批量处理命令,可能会花很长时间,但是你可能不想让你的程序等着结果返回,而是给你返回一个任务ID,过一段时间只要拿着这个任务ID就可以拿到任务执行结果。

场景3:
你想做一个定时任务,比如每天检测一下你们所有客户的资料,如果发现今天是某个客户的生日,就给他发个短信祝福。

1 Celery介绍

Celery是一个基于python开发的分布式异步消息的任务队列

Celery优点:

  1. 简单。
  2. 高可用。当任务执行失败或者执行过程中发生中断,Celery会自动尝试重新执行任务
  3. 快速。一个单进程的celery每分钟可处理上百万个任务
  4. 灵活。几乎celery的每个组件都可以被扩展和自定制。

Celery分为3个部分
(1)worker部分负责任务的处理,即工作进程(我的理解工作进程就是你写的python代码,当然还包括python调用系统工具功能)
(2)broker部分负责任务消息的分发以及任务结果的存储,这部分任务主要由中间数据存储系统完成,比如消息队列服务器RabbitMQ、redis。作为一个消息中间件。
(3)Celery主类,进行任务最开始的指派与执行控制,他可以是单独的python脚本,也可以和其他程序结合,应用到django或者flask等web框架里面以及你能想到的任何应用

celery的模块架构

工作原理

Celery Flower

Flower是基于Celery web的监控和管理

celery的运用比较简单:
1.安装celery   
2 创建一个celery application 用来定义你的任务列表

3.编写需要异步执行的任务函数,并用celery实例的task修饰器修饰

4.调用异步任务时, 用函数名.delay(参数)形式调用为异步调用。 函数名(参数)方式为同步调用。

5.执行celery监听服务

2 安装celery

source ~/python3.6_env/bin/activate

(python3.6_env) $ pip install celery==4.1.0

(python3.6_env) $ pip install redis

安装celery flower

(python3.6_env) $ pip install flower

安装django-celery

(python3.6_env) $pip install django-celery

我们总在说c10k的问题, 也做了不少优化, 然后优化总是不够的。

其中的一个瓶颈就是一些耗时的操作(网络请求/文件操作–含耗时的数据库操作)。

如果我们不关心他们的返回值,则可以将其做成异步任务,保证执行成功即可。

3 Celery使用案例

案例1 任务调度执行:

(1)创建一个celery application 用来定义你的任务列表

编译一个tasks.py 文件

#!/usr/bin/env python  
# encoding: utf-8

from celery import Celery
from time  import sleep

# broker="redis://redis:6379/1" 列队数据库存放点
# backend="redis://redis:6379/2" 任务执行完成后数据库存放点
//创建一个celery application 用来定义你的任务列表
app=Celery("tasks",  broker="redis://127.0.0.1:6379/1",
         backend="redis://127.0.0.1:6379/2")

@app.task
def add(x,y):
        return x + y

@app.task
def mult(x,y):
        sleep(10)
        return x * y

@app.task
def getname(name):
        return name
        
@app.task
def sendmail(user_email):
     func(user_email)
     return True

(2)启动Celery Worker来开始监听并执行任务

celery -A tasks worker --loglevel=info

(3)服务使用方调用任务

 再打开一个终端, 进行命令行模式,调用任务

add.delay(6, 5)

<AsyncResult: a324e552-90db-4e12-8b97-1539471c4bb2>

观察服务端变化

案例2. Celery实现定时器

from celery import Celery
from celery.schedules import crontab

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

#@app.on_after_configure.connect
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
    # Calls test('hello') every 10 seconds.
    sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')

    # Calls test('world') every 30 seconds
    sender.add_periodic_task(30.0, test.s('world'), expires=10)

    # Executes every Monday morning at 7:30 a.m.
    sender.add_periodic_task(crontab(hour=7, minute=30, day_of_week=1), test.s('Happy Mondays!'),)


@app.task
def test(arg):
    print(arg)

开启两个终端

(1)一个终端启动worker

celery worker -A tasks -l INFO

(2)另一个终端启动调度器 beat (组件 beat,它用于对任务进行调度)

celery beat -A tasks -l INFO

为了快速部署并启动服务,我们可以写一个Celery管理脚本程序

celery管理脚本

#!/bin/bash
#############################################################
#celery flower web ui controller script
# web reference : https://my.oschina.net/u/2306127/blog/420929
############################################################
CELERY_UI_PORT=10055

BROKER="redis://127.0.0.1:6379/1"
#BROKER="redis://172.16.245.100:6379/1"

APP_NAME="worker"

#start the celery ui web server.
start_celery_flower() {
   nohup celery flower --broker=$BROKER  --port=$CELERY_UI_PORT >./flower.log 2>./flower.log  &  
   #nohup celery flower --broker=$BROKER  --port=$CELERY_UI_PORT >/dev/null 2>/dev/null  &  
   #celery flower --broker=$BROKER  --port=$CELERY_UI_PORT  -A $APP_NAME &
   echo "start celery ui server ok with $CELERY_UI_PORT"
}

#start the celery app start
#params: 
#    -A   app name
#    -l   log level
#    -c   concurrency num
start_celery_app() {
  #celery worker --workdir tasks -A  $APP_NAME  -l info 
  nohup celery worker --workdir tasks  -A $APP_NAME  -l info -c 2 >./app.log 2>.app.log  &
  #celery worker -A  $APP_NAME  -l info -c 5
}

test_app(){
    python tasks/client.py
}

stop_celery_app(){
  killall celery
}

case $1 in
    flower) 
        start_celery_flower
        ;;
    app)
        start_celery_app
        ;;
    test)
        test_app
        ;;
    stop)
        stop_celery_app
        ;;
    help)
        echo "./celery_ctl.sh flower | app  | test| stop "
        ;;
      *)
        echo "./celery_ctl.sh flower | app  | test | stop "
        exit 2
esac

知识扩展:

NC (netcat)

实现远程拷贝和网络监听服务

Ubuntu自带nc工具

NC应用的场景:

(1)TCP端口扫描

# nc -v -z -w2 127.0.0.1 1-100
Connection to 127.0.0.1 22 port [tcp/ssh] succeeded!
Connection to 127.0.0.1 53 port [tcp/domain] succeeded!
Connection to 127.0.0.1 80 port [tcp/http] succeeded!
...
nc: connect to 127.0.0.1 port 100 (tcp) failed: Connection refused

(2)拷贝文件

从192.168.1.2拷贝文件到192.168.1.3

首先在接收端192.168.1.3上: nc -l 1234 > test.txt //开启接收的文件端口

然后在发送端192.168.1.2上: nc 192.168.1.3 1234 < test.txt //往指定端口上发送文件

(3)简单聊天工具

在192.168.1.2上: nc -l 1234

在192.168.1.3上: nc 192.168.1.2 1234

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值