Python3.7+Tornado5.1.1+Celery3.1+Rabbitmq3.7.16實現異步隊列任務

原文轉載自「劉悅的技術博客」https://v3u.cn/a_id_99

在之前的一篇文章中提到了用Django+Celery+Redis實現了異步任務隊列,只不過消息中間件使用了redis,redis作爲消息中間件可謂是差強人意,功能和性能上都不如Rabbitmq,所以本次使用tornado框架結合celery,同時消息中間件使用Rabbitmq來實現異步發郵件,並且使用flower來監控任務隊列。

首先安裝rabbitmq

Mac os直接運行brew命令安裝

#安裝服務
brew install rabbitmq
#啓動服務
brew services start rabbitmq

Win10系統就要下載安裝包進行安裝了,由於rabbitmq是基於erlang的,所以要首先安裝erlang

1、首先,下載並運行Erlang for Windows 安裝程序 (地址:http://www.erlang.org/downloads)下載完畢並安裝(注意:安裝目錄請選擇默認目錄)

2、下載 RabbitMQ,(地址:http://www.rabbitmq.com/download.html )(注意:安裝目錄請選擇默認目錄)

安裝成功後,啓用web管理UI,進入RabbitMQ Serverrabbitmq_server-3.6.6sbin,輸入命令rabbitmq-plugins enable rabbitmq_management

在系統的開始菜單裏找到RabbitMQ的啓動菜單,啓動服務

瀏覽器輸入,http://localhost:15672/,使用默認用戶guest/guest進入網頁端控制檯:

代表沒有問題了

然後安裝tornado和celery,注意指定版本號

pip3 install tornado==5.1.1
pip3 install celery ==3.1
pip3 install pika ==0.9.14
pip3 install tornado-celery
pip3 install flower

需要注意一點,由於python3.7中async已經作爲關鍵字存在,但是有的三方庫還沒有及時修正,導致它們自己聲明的變量和系統關鍵字重名,所以我們要深入三方庫的源碼,幫他們修改async關鍵字爲async_my,需要修改的文件夾和文件包含但不限於:

/site-packages/pika/adapters/libev_connection.py

/site-packages/celery下面的文件

/site-packages/kombu下面的文件夾

在tornado項目下新建一個任務隊列文件task.py:

import time
from celery import Celery
from func_tool import mail

C_FORCE_ROOT=True

celery = Celery("tasks", broker="amqp://guest:guest@localhost:5672")
celery.conf.CELERY_RESULT_BACKEND = "amqp"


@celery.task
def sleep(seconds):
    time.sleep(float(seconds))
    return seconds

@celery.task
def sendmail(title,text,tomail):
    mail(title,text,tomail)
    return '發送郵件成功'

if __name__ == "__main__":
    celery.start()

然後編寫服務端代碼:

from celery import Celery
from tornado import gen
import tcelery
sys.path.append("..")
import task

#異步任務
class CeleryHandler(BaseHandler):
    @gen.coroutine
    def get(self):
        response = yield gen.Task(task.sendmail.apply_async,args=['你好','非常好','[email protected]'])
        self.write('ok')
        self.finish()

路由器代碼:

import tornado.web
from views import Index
import config


#路由 

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/celery", Index.CeleryHandler)
        ]
        super(Application,self).__init__(handlers,**config.setting)

程序入口代碼server.py:

import tornado.ioloop
import tornado.httpserver
import config
 
from application import Application
 
 
 
 
if __name__ == "__main__":
    print('啓動...')
    app = Application()
    httpServer = tornado.httpserver.HTTPServer(app)
    # httpServer.listen(8888)
    #綁定端口
    httpServer.bind(config.options['port'])
    #開啓5個子進程(默認1,若爲None或者小於0,開啓對應硬件的CPU核心數個子進程)
    httpServer.start(1)
    tornado.ioloop.IOLoop.current().start()

進入項目目錄,分別啓動tornado服務,celery服務,以及flower服務

python server.py
celery -A task worker --loglevel=info
celery flower -A task --broker=amqp://guest:guest@localhost:5672//

訪問網址http://localhost:8000/celery 用來觸發異步任務

後臺服務顯示任務返回值:

進入flower在線任務監控網址:http://localhost:5555/

至此,整個流程就走完了。

原文轉載自「劉悅的技術博客」 https://v3u.cn/a_id_99

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章