tornado搭建server 实现 celery 定时任务

tornado 是一个异步服务器框架,性能不错的,这里搭建一个简单的 server,来调用celery 创建 定时任务
异步任务的实现原理也相对简单,因为中间 broker 的存在,其实也就是将客户端和服务器分开了。那么定时任务又是怎么个道理呢?其实定时任务是一种特别的异步任务,原理和异步任务一样,但是,有一样不相同的就是定时任务的客户端是定时器,我们设置定时任务的执行周期,然后就交给 Celery 定期得帮我们触发异步任务。

首先需要知道要想使用 Celery 的定时任务,我们需要启动两个东西,分别是:

  • 定时器,也叫作 beater,也就是帮助我们计算什么时候执行什么操作
  • 执行器,也叫作 worker,真正执行任务的地方,我们的任务都是通过这个运行的

 

安装:

pip install celery 

pip install tornado

 

目录图:

 

 

tasks.py

import time
from celery.bin import worker as celery_worker
from celery import Celery, platforms
from datetime import timedelta
from urllib import request
from tornado.httpclient import HTTPClient
 
platforms.C_FORCE_ROOT = True
broker = 'amqp://admin:guest@127.0.0.1:5672/'
backend = 'redis://127.0.0.1:6379/2'
 
celery = Celery('tasks', broker=broker, backend=backend)
 
celery.conf.update(
    CELERYBEAT_SCHEDULE={
        'perminute': {
            'task': 'tasks.asyget',
            'schedule': timedelta(seconds=1),
            'args': ['http://www.baidu.com'],
        }
    }
)
 
 
@celery.task
def asyget(urls):
    """
    req = request.Request(url='%s' % (urls))
    res = request.urlopen(req)
    res = res.read()
    print(res.decode(encoding='utf-8'))
    """
    
    http_client = HTTPClient()
    response = http_client.fetch(urls)
    print(response.body)
 
 
@celery.task
def print_time():
    print("now is: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
 
 
def worker_start():
    worker = celery_worker.worker(app=celery)
    worker.run(
        broker=broker,
        concurrency=4,
        traceback=False,
        loglevel='INFO'
    )
 
 
if __name__ == '__main__':
    worker_start()

  

server.py

import tornado.ioloop
import tornado.web
from tasks import *
 
 
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("haody, tornado")
        asyget.delay(['http://www.baidu.com'])
 
 
class TaskHandler(tornado.web.RequestHandler):
    def get(self):
        taskname = self.get_argument('taskname')
        if taskname == "geturl":
            self.write("run task:" + taskname)
            asyget.delay(['http://www.baidu.com'])
 
        if taskname == "ptime":
            self.write("run task:" + taskname)
            print_time.delay()
 
 
application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/api/task/", TaskHandler),
])
 
if __name__ == "__main__":
    application.listen(9000)
    tornado.ioloop.IOLoop.instance().start()

 

 

在当根目录下执行

运行任务:
运行定时器:

celery beat -A tasks --loglevel=info

 

运行执行器: ( windows 环境下需要加上 -P eventlet , linux 不需要 )

celery worker -A tasks -l info -P eventlet

定时任务实现解析
在上面一节中,其实真正是和定时有关的代码是这一段:

app.conf.update(
    CELERYBEAT_SCHEDULE={
        'perminute': {
            'task': 'tasks.add',
            'schedule': timedelta(seconds=3),
            'args': (1, 1)
        }
    }
)

我们这里添加了一个名字叫做  perminute  的任务,然后里面设置这个任务的详情,这里的意思就是说每隔3秒钟就执行一次  tasks.add  这个任务,并且使用的参数是  1, 1 。这里只要求了一个任务,我们可以多加几个任务,例如:

 
app.conf.update(
    CELERYBEAT_SCHEDULE={
        'add_task': {
            'task': 'tasks.add',
            'schedule': timedelta(seconds=3),
            'args': (1, 1)
        },
        'sub_task': {
            'task': 'tasks.sub',
            'schedule': timedelta(seconds=3),
            'args': (1, 1)
        }
    }
)

 

python url lib 库模拟get请求耗时:

tornado httpclient 异步请求耗时:

 

运行 tornado server : 

python server.py

  

 

根目录下执行:

启动 flower ui:

celery flower -A tasks  --port = 5555

http://localhost:5555

 源地址:https://blog.csdn.net/weixin_39616762/article/details/79419684

 

posted @ 2022-04-20 11:32  Wolf_Stark  阅读(426)  评论(0)    收藏  举报