原文轉載自「劉悅的技術博客」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