安裝:
??
tornado 多進程 數據同步
tornado mysql
Tornado 標榜的是 asynchronous 和 non-blocking,然而,很多時候一不小心一不講究就會把整個 tornado 阻塞住,特別是做 MySQL 操作時。本文簡述兩種在 tornado 中異步無阻塞地使用 MySQL 的方法。
常見的阻塞情況
class Handler(tornado.web.RequestHandler):
def get(self):
connection = pymysql.connect() # 連接數據庫的相關參數省略
with connection.cursor() as cursor:
sql = '這裏應該有一條SQL查詢語句'
cursor.execute(sql)
result = cursor.fetchone()
self.write(str(result['id']))
以上這種情景,tornado 會在 pymysql.connect() 和 cursor.execute(sql) 的地方阻塞住,無法響應其他 request。
無阻塞方案1:使用 Tornado-MySQL 作者不維護,不用爲好。
無阻塞方案2:使用 Celery
Celery 是一個異步的任務隊列,它能很方便地支持分佈式擴展,因而很適合將 tornado 中的長時間的阻塞工作交由 Celery 來完成。 而要 Celery 配合 Tornado 一起工作,需要藉助一個名爲 tornado-celery 請戳 pypi 頁面的包。
看例子,首先是 tornado handler 的代碼:
import tornado.gen
import tornado.web
import tcelery
import mysql_task
tcelery.setup_nonblocking_producer()
class Handler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self):
result = yield tornado.gen.Task(mysql_task.mysql_test.apply_async)
self.write(result)
self.finish()
而具體操作 MySQL 的部分則擺在 mysql_task.py 文件中。至於 celery worker 的寫法這裏就省略掉了。
特別需要注意的是:tornado-celery 目前只支持 AMQP 的 backend。