1. 程式人生 > >在tornado中使用異步mysql操作

在tornado中使用異步mysql操作

ini 響應 ref 沒有 pan war 做到 tor l數據庫

在使用tornado框架進行開發的過程中,發現tornado的mysql數據庫操作並不是一步的,造成了所有用戶行為的堵塞.tornado本身是一個異步的框架,要求所有的操作都應該是異步的,但是數據庫這一層就把整個服務器都拖住了.

##查找到的解決辦法:

  1. 使用異步的mysql操作庫. 查找了一下,有兩個比較完善的異步操作庫
    一個是AsyncTorndb,國人自己寫的異步操作,看了一下,好像不錯的樣子,但是沒有響應的測試用例,不敢用.

    一個是Tornado-MySQL是對PyMySQL的異步化的一個庫,測試用例,文檔,都比較齊全,可以嘗試使用.

2.仿照(torngas)[https://github.com/mqingyn/torngas]的異步線程池,使用tornado的concurrent.run_on_executor裝飾器對數據庫操作進行異步化

3.使用任務隊列,太過麻煩,對之前的代碼修改過大,不使用該方案

  • 在使用Tornado-MySQL過程中,發現對現有代碼更改太過嚴重,放棄,使用了異步線程池的方式.做到最小的代碼更改以及異步數據庫操作的實現

##如何使用異步線程池concurrent.run_on_executor

  1. 在原先的同步的數據庫執行的方法添加@concurrent.run_on_executor裝飾器,如以下例子:

    1
    2
    3
    4
    5
    6
    7
    @concurrent.run_on_executor
    def runSql(self):
    t = time.time()
    db = client.conn()
    db.execute(‘‘‘select * from TABLE_CONSTRAINTS join (CHARACTER_SETS,STATISTICS)‘‘‘)
    db.close()
    return time.time() - t
  1. 在調用該方法的函數使用yield tornado.gen.Task(functionName) 調用上面的修改的方法,並且為主函數添加@tornado.gen.engine裝飾器,如以下例子(tordona框架中的requestHander中的get方法):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self, *args, **kwargs):
    # print self.get_query_argument("test11")
    time = yield tornado.gen.Task(self.runSql)
    print time
    self.write(unicode(time))
    print "over"
    self.finish()

    *使用@tornado.web.asynchronous 裝飾器取消requestHander的自動finish,不然無法等待異步sql執行完畢再返回數據

在tornado中使用異步mysql操作