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

浙公网安备 33010602011771号